OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [xtensa/] [xtensa.c] - Blame information for rev 303

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

Line No. Rev Author Line
1 282 jeremybenn
/* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2
   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3
   Free Software Foundation, Inc.
4
   Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "rtl.h"
27
#include "regs.h"
28
#include "hard-reg-set.h"
29
#include "basic-block.h"
30
#include "real.h"
31
#include "insn-config.h"
32
#include "conditions.h"
33
#include "insn-flags.h"
34
#include "insn-attr.h"
35
#include "insn-codes.h"
36
#include "recog.h"
37
#include "output.h"
38
#include "tree.h"
39
#include "expr.h"
40
#include "flags.h"
41
#include "reload.h"
42
#include "tm_p.h"
43
#include "function.h"
44
#include "toplev.h"
45
#include "optabs.h"
46
#include "libfuncs.h"
47
#include "ggc.h"
48
#include "target.h"
49
#include "target-def.h"
50
#include "langhooks.h"
51
#include "gimple.h"
52
#include "df.h"
53
 
54
 
55
/* Enumeration for all of the relational tests, so that we can build
56
   arrays indexed by the test type, and not worry about the order
57
   of EQ, NE, etc.  */
58
 
59
enum internal_test
60
{
61
  ITEST_EQ,
62
  ITEST_NE,
63
  ITEST_GT,
64
  ITEST_GE,
65
  ITEST_LT,
66
  ITEST_LE,
67
  ITEST_GTU,
68
  ITEST_GEU,
69
  ITEST_LTU,
70
  ITEST_LEU,
71
  ITEST_MAX
72
};
73
 
74
/* Array giving truth value on whether or not a given hard register
75
   can support a given mode.  */
76
char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
77
 
78
/* Current frame size calculated by compute_frame_size.  */
79
unsigned xtensa_current_frame_size;
80
 
81
/* Largest block move to handle in-line.  */
82
#define LARGEST_MOVE_RATIO 15
83
 
84
/* Define the structure for the machine field in struct function.  */
85
struct GTY(()) machine_function
86
{
87
  int accesses_prev_frame;
88
  bool need_a7_copy;
89
  bool vararg_a7;
90
  rtx vararg_a7_copy;
91
  rtx set_frame_ptr_insn;
92
};
93
 
94
/* Vector, indexed by hard register number, which contains 1 for a
95
   register that is allowable in a candidate for leaf function
96
   treatment.  */
97
 
98
const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
99
{
100
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
101
  1, 1, 1,
102
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
103
  1
104
};
105
 
106
/* Map hard register number to register class */
107
const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
108
{
109
  RL_REGS,      SP_REG,         RL_REGS,        RL_REGS,
110
  RL_REGS,      RL_REGS,        RL_REGS,        GR_REGS,
111
  RL_REGS,      RL_REGS,        RL_REGS,        RL_REGS,
112
  RL_REGS,      RL_REGS,        RL_REGS,        RL_REGS,
113
  AR_REGS,      AR_REGS,        BR_REGS,
114
  FP_REGS,      FP_REGS,        FP_REGS,        FP_REGS,
115
  FP_REGS,      FP_REGS,        FP_REGS,        FP_REGS,
116
  FP_REGS,      FP_REGS,        FP_REGS,        FP_REGS,
117
  FP_REGS,      FP_REGS,        FP_REGS,        FP_REGS,
118
  ACC_REG,
119
};
120
 
121
static enum internal_test map_test_to_internal_test (enum rtx_code);
122
static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
123
static rtx gen_float_relational (enum rtx_code, rtx, rtx);
124
static rtx gen_conditional_move (enum rtx_code, enum machine_mode, rtx, rtx);
125
static rtx fixup_subreg_mem (rtx);
126
static struct machine_function * xtensa_init_machine_status (void);
127
static rtx xtensa_legitimize_tls_address (rtx);
128
static rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
129
static bool xtensa_return_in_msb (const_tree);
130
static void printx (FILE *, signed int);
131
static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
132
static rtx xtensa_builtin_saveregs (void);
133
static bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
134
static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
135
                                                        int) ATTRIBUTE_UNUSED;
136
static section *xtensa_select_rtx_section (enum machine_mode, rtx,
137
                                           unsigned HOST_WIDE_INT);
138
static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
139
static tree xtensa_build_builtin_va_list (void);
140
static bool xtensa_return_in_memory (const_tree, const_tree);
141
static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
142
                                         gimple_seq *);
143
static rtx xtensa_function_value (const_tree, const_tree, bool);
144
static void xtensa_init_builtins (void);
145
static tree xtensa_fold_builtin (tree, tree, bool);
146
static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
147
static void xtensa_va_start (tree, rtx);
148
static bool xtensa_frame_pointer_required (void);
149
static rtx xtensa_static_chain (const_tree, bool);
150
static void xtensa_asm_trampoline_template (FILE *);
151
static void xtensa_trampoline_init (rtx, tree, rtx);
152
 
153
static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
154
  REG_ALLOC_ORDER;
155
 
156
 
157
/* This macro generates the assembly code for function exit,
158
   on machines that need it.  If FUNCTION_EPILOGUE is not defined
159
   then individual return instructions are generated for each
160
   return statement.  Args are same as for FUNCTION_PROLOGUE.  */
161
 
162
#undef TARGET_ASM_FUNCTION_EPILOGUE
163
#define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
164
 
165
/* These hooks specify assembly directives for creating certain kinds
166
   of integer object.  */
167
 
168
#undef TARGET_ASM_ALIGNED_SI_OP
169
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
170
 
171
#undef TARGET_ASM_SELECT_RTX_SECTION
172
#define TARGET_ASM_SELECT_RTX_SECTION  xtensa_select_rtx_section
173
 
174
#undef TARGET_DEFAULT_TARGET_FLAGS
175
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
176
 
177
#undef TARGET_LEGITIMIZE_ADDRESS
178
#define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
179
 
180
#undef TARGET_RTX_COSTS
181
#define TARGET_RTX_COSTS xtensa_rtx_costs
182
#undef TARGET_ADDRESS_COST
183
#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
184
 
185
#undef TARGET_BUILD_BUILTIN_VA_LIST
186
#define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
187
 
188
#undef TARGET_EXPAND_BUILTIN_VA_START
189
#define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
190
 
191
#undef TARGET_PROMOTE_FUNCTION_MODE
192
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
193
#undef TARGET_PROMOTE_PROTOTYPES
194
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
195
 
196
#undef TARGET_RETURN_IN_MEMORY
197
#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
198
#undef TARGET_FUNCTION_VALUE
199
#define TARGET_FUNCTION_VALUE xtensa_function_value
200
#undef TARGET_SPLIT_COMPLEX_ARG
201
#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
202
#undef TARGET_MUST_PASS_IN_STACK
203
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
204
 
205
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
206
#define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
207
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
208
#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
209
 
210
#undef TARGET_RETURN_IN_MSB
211
#define TARGET_RETURN_IN_MSB xtensa_return_in_msb
212
 
213
#undef  TARGET_INIT_BUILTINS
214
#define TARGET_INIT_BUILTINS xtensa_init_builtins
215
#undef  TARGET_FOLD_BUILTIN
216
#define TARGET_FOLD_BUILTIN xtensa_fold_builtin
217
#undef  TARGET_EXPAND_BUILTIN
218
#define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
219
 
220
#undef TARGET_SECONDARY_RELOAD
221
#define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
222
 
223
#undef TARGET_HAVE_TLS
224
#define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
225
 
226
#undef TARGET_CANNOT_FORCE_CONST_MEM
227
#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
228
 
229
#undef TARGET_LEGITIMATE_ADDRESS_P
230
#define TARGET_LEGITIMATE_ADDRESS_P     xtensa_legitimate_address_p
231
 
232
#undef TARGET_FRAME_POINTER_REQUIRED
233
#define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
234
 
235
#undef TARGET_STATIC_CHAIN
236
#define TARGET_STATIC_CHAIN xtensa_static_chain
237
#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
238
#define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
239
#undef TARGET_TRAMPOLINE_INIT
240
#define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
241
 
242
struct gcc_target targetm = TARGET_INITIALIZER;
243
 
244
 
245
/* Functions to test Xtensa immediate operand validity.  */
246
 
247
bool
248
xtensa_simm8 (HOST_WIDE_INT v)
249
{
250
  return v >= -128 && v <= 127;
251
}
252
 
253
 
254
bool
255
xtensa_simm8x256 (HOST_WIDE_INT v)
256
{
257
  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
258
}
259
 
260
 
261
bool
262
xtensa_simm12b (HOST_WIDE_INT v)
263
{
264
  return v >= -2048 && v <= 2047;
265
}
266
 
267
 
268
static bool
269
xtensa_uimm8 (HOST_WIDE_INT v)
270
{
271
  return v >= 0 && v <= 255;
272
}
273
 
274
 
275
static bool
276
xtensa_uimm8x2 (HOST_WIDE_INT v)
277
{
278
  return (v & 1) == 0 && (v >= 0 && v <= 510);
279
}
280
 
281
 
282
static bool
283
xtensa_uimm8x4 (HOST_WIDE_INT v)
284
{
285
  return (v & 3) == 0 && (v >= 0 && v <= 1020);
286
}
287
 
288
 
289
static bool
290
xtensa_b4const (HOST_WIDE_INT v)
291
{
292
  switch (v)
293
    {
294
    case -1:
295
    case 1:
296
    case 2:
297
    case 3:
298
    case 4:
299
    case 5:
300
    case 6:
301
    case 7:
302
    case 8:
303
    case 10:
304
    case 12:
305
    case 16:
306
    case 32:
307
    case 64:
308
    case 128:
309
    case 256:
310
      return true;
311
    }
312
  return false;
313
}
314
 
315
 
316
bool
317
xtensa_b4const_or_zero (HOST_WIDE_INT v)
318
{
319
  if (v == 0)
320
    return true;
321
  return xtensa_b4const (v);
322
}
323
 
324
 
325
bool
326
xtensa_b4constu (HOST_WIDE_INT v)
327
{
328
  switch (v)
329
    {
330
    case 32768:
331
    case 65536:
332
    case 2:
333
    case 3:
334
    case 4:
335
    case 5:
336
    case 6:
337
    case 7:
338
    case 8:
339
    case 10:
340
    case 12:
341
    case 16:
342
    case 32:
343
    case 64:
344
    case 128:
345
    case 256:
346
      return true;
347
    }
348
  return false;
349
}
350
 
351
 
352
bool
353
xtensa_mask_immediate (HOST_WIDE_INT v)
354
{
355
#define MAX_MASK_SIZE 16
356
  int mask_size;
357
 
358
  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
359
    {
360
      if ((v & 1) == 0)
361
        return false;
362
      v = v >> 1;
363
      if (v == 0)
364
        return true;
365
    }
366
 
367
  return false;
368
}
369
 
370
 
371
/* This is just like the standard true_regnum() function except that it
372
   works even when reg_renumber is not initialized.  */
373
 
374
int
375
xt_true_regnum (rtx x)
376
{
377
  if (GET_CODE (x) == REG)
378
    {
379
      if (reg_renumber
380
          && REGNO (x) >= FIRST_PSEUDO_REGISTER
381
          && reg_renumber[REGNO (x)] >= 0)
382
        return reg_renumber[REGNO (x)];
383
      return REGNO (x);
384
    }
385
  if (GET_CODE (x) == SUBREG)
386
    {
387
      int base = xt_true_regnum (SUBREG_REG (x));
388
      if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
389
        return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
390
                                           GET_MODE (SUBREG_REG (x)),
391
                                           SUBREG_BYTE (x), GET_MODE (x));
392
    }
393
  return -1;
394
}
395
 
396
 
397
int
398
xtensa_valid_move (enum machine_mode mode, rtx *operands)
399
{
400
  /* Either the destination or source must be a register, and the
401
     MAC16 accumulator doesn't count.  */
402
 
403
  if (register_operand (operands[0], mode))
404
    {
405
      int dst_regnum = xt_true_regnum (operands[0]);
406
 
407
      /* The stack pointer can only be assigned with a MOVSP opcode.  */
408
      if (dst_regnum == STACK_POINTER_REGNUM)
409
        return (mode == SImode
410
                && register_operand (operands[1], mode)
411
                && !ACC_REG_P (xt_true_regnum (operands[1])));
412
 
413
      if (!ACC_REG_P (dst_regnum))
414
        return true;
415
    }
416
  if (register_operand (operands[1], mode))
417
    {
418
      int src_regnum = xt_true_regnum (operands[1]);
419
      if (!ACC_REG_P (src_regnum))
420
        return true;
421
    }
422
  return FALSE;
423
}
424
 
425
 
426
int
427
smalloffset_mem_p (rtx op)
428
{
429
  if (GET_CODE (op) == MEM)
430
    {
431
      rtx addr = XEXP (op, 0);
432
      if (GET_CODE (addr) == REG)
433
        return BASE_REG_P (addr, 0);
434
      if (GET_CODE (addr) == PLUS)
435
        {
436
          rtx offset = XEXP (addr, 0);
437
          HOST_WIDE_INT val;
438
          if (GET_CODE (offset) != CONST_INT)
439
            offset = XEXP (addr, 1);
440
          if (GET_CODE (offset) != CONST_INT)
441
            return FALSE;
442
 
443
          val = INTVAL (offset);
444
          return (val & 3) == 0 && (val >= 0 && val <= 60);
445
        }
446
    }
447
  return FALSE;
448
}
449
 
450
 
451
int
452
constantpool_address_p (rtx addr)
453
{
454
  rtx sym = addr;
455
 
456
  if (GET_CODE (addr) == CONST)
457
    {
458
      rtx offset;
459
 
460
      /* Only handle (PLUS (SYM, OFFSET)) form.  */
461
      addr = XEXP (addr, 0);
462
      if (GET_CODE (addr) != PLUS)
463
        return FALSE;
464
 
465
      /* Make sure the address is word aligned.  */
466
      offset = XEXP (addr, 1);
467
      if ((GET_CODE (offset) != CONST_INT)
468
          || ((INTVAL (offset) & 3) != 0))
469
        return FALSE;
470
 
471
      sym = XEXP (addr, 0);
472
    }
473
 
474
  if ((GET_CODE (sym) == SYMBOL_REF)
475
      && CONSTANT_POOL_ADDRESS_P (sym))
476
    return TRUE;
477
  return FALSE;
478
}
479
 
480
 
481
int
482
constantpool_mem_p (rtx op)
483
{
484
  if (GET_CODE (op) == SUBREG)
485
    op = SUBREG_REG (op);
486
  if (GET_CODE (op) == MEM)
487
    return constantpool_address_p (XEXP (op, 0));
488
  return FALSE;
489
}
490
 
491
 
492
/* Return TRUE if X is a thread-local symbol.  */
493
 
494
static bool
495
xtensa_tls_symbol_p (rtx x)
496
{
497
  if (! TARGET_HAVE_TLS)
498
    return false;
499
 
500
  return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
501
}
502
 
503
 
504
void
505
xtensa_extend_reg (rtx dst, rtx src)
506
{
507
  rtx temp = gen_reg_rtx (SImode);
508
  rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
509
 
510
  /* Generate paradoxical subregs as needed so that the modes match.  */
511
  src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
512
  dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
513
 
514
  emit_insn (gen_ashlsi3 (temp, src, shift));
515
  emit_insn (gen_ashrsi3 (dst, temp, shift));
516
}
517
 
518
 
519
bool
520
xtensa_mem_offset (unsigned v, enum machine_mode mode)
521
{
522
  switch (mode)
523
    {
524
    case BLKmode:
525
      /* Handle the worst case for block moves.  See xtensa_expand_block_move
526
         where we emit an optimized block move operation if the block can be
527
         moved in < "move_ratio" pieces.  The worst case is when the block is
528
         aligned but has a size of (3 mod 4) (does this happen?) so that the
529
         last piece requires a byte load/store.  */
530
      return (xtensa_uimm8 (v)
531
              && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
532
 
533
    case QImode:
534
      return xtensa_uimm8 (v);
535
 
536
    case HImode:
537
      return xtensa_uimm8x2 (v);
538
 
539
    case DFmode:
540
      return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
541
 
542
    default:
543
      break;
544
    }
545
 
546
  return xtensa_uimm8x4 (v);
547
}
548
 
549
 
550
/* Make normal rtx_code into something we can index from an array.  */
551
 
552
static enum internal_test
553
map_test_to_internal_test (enum rtx_code test_code)
554
{
555
  enum internal_test test = ITEST_MAX;
556
 
557
  switch (test_code)
558
    {
559
    default:                    break;
560
    case EQ:  test = ITEST_EQ;  break;
561
    case NE:  test = ITEST_NE;  break;
562
    case GT:  test = ITEST_GT;  break;
563
    case GE:  test = ITEST_GE;  break;
564
    case LT:  test = ITEST_LT;  break;
565
    case LE:  test = ITEST_LE;  break;
566
    case GTU: test = ITEST_GTU; break;
567
    case GEU: test = ITEST_GEU; break;
568
    case LTU: test = ITEST_LTU; break;
569
    case LEU: test = ITEST_LEU; break;
570
    }
571
 
572
  return test;
573
}
574
 
575
 
576
/* Generate the code to compare two integer values.  The return value is
577
   the comparison expression.  */
578
 
579
static rtx
580
gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
581
                    rtx cmp0, /* first operand to compare */
582
                    rtx cmp1, /* second operand to compare */
583
                    int *p_invert /* whether branch needs to reverse test */)
584
{
585
  struct cmp_info
586
  {
587
    enum rtx_code test_code;    /* test code to use in insn */
588
    bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
589
    int const_add;              /* constant to add (convert LE -> LT) */
590
    int reverse_regs;           /* reverse registers in test */
591
    int invert_const;           /* != 0 if invert value if cmp1 is constant */
592
    int invert_reg;             /* != 0 if invert value if cmp1 is register */
593
    int unsignedp;              /* != 0 for unsigned comparisons.  */
594
  };
595
 
596
  static struct cmp_info info[ (int)ITEST_MAX ] = {
597
 
598
    { EQ,       xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },     /* EQ  */
599
    { NE,       xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },     /* NE  */
600
 
601
    { LT,       xtensa_b4const_or_zero, 1, 1, 1, 0, 0 },  /* GT  */
602
    { GE,       xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },     /* GE  */
603
    { LT,       xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },     /* LT  */
604
    { GE,       xtensa_b4const_or_zero, 1, 1, 1, 0, 0 },  /* LE  */
605
 
606
    { LTU,      xtensa_b4constu,        1, 1, 1, 0, 1 }, /* GTU */
607
    { GEU,      xtensa_b4constu,        0, 0, 0, 0, 1 },    /* GEU */
608
    { LTU,      xtensa_b4constu,        0, 0, 0, 0, 1 },    /* LTU */
609
    { GEU,      xtensa_b4constu,        1, 1, 1, 0, 1 }, /* LEU */
610
  };
611
 
612
  enum internal_test test;
613
  enum machine_mode mode;
614
  struct cmp_info *p_info;
615
 
616
  test = map_test_to_internal_test (test_code);
617
  gcc_assert (test != ITEST_MAX);
618
 
619
  p_info = &info[ (int)test ];
620
 
621
  mode = GET_MODE (cmp0);
622
  if (mode == VOIDmode)
623
    mode = GET_MODE (cmp1);
624
 
625
  /* Make sure we can handle any constants given to us.  */
626
  if (GET_CODE (cmp1) == CONST_INT)
627
    {
628
      HOST_WIDE_INT value = INTVAL (cmp1);
629
      unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
630
 
631
      /* if the immediate overflows or does not fit in the immediate field,
632
         spill it to a register */
633
 
634
      if ((p_info->unsignedp ?
635
           (uvalue + p_info->const_add > uvalue) :
636
           (value + p_info->const_add > value)) != (p_info->const_add > 0))
637
        {
638
          cmp1 = force_reg (mode, cmp1);
639
        }
640
      else if (!(p_info->const_range_p) (value + p_info->const_add))
641
        {
642
          cmp1 = force_reg (mode, cmp1);
643
        }
644
    }
645
  else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
646
    {
647
      cmp1 = force_reg (mode, cmp1);
648
    }
649
 
650
  /* See if we need to invert the result.  */
651
  *p_invert = ((GET_CODE (cmp1) == CONST_INT)
652
               ? p_info->invert_const
653
               : p_info->invert_reg);
654
 
655
  /* Comparison to constants, may involve adding 1 to change a LT into LE.
656
     Comparison between two registers, may involve switching operands.  */
657
  if (GET_CODE (cmp1) == CONST_INT)
658
    {
659
      if (p_info->const_add != 0)
660
        cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
661
 
662
    }
663
  else if (p_info->reverse_regs)
664
    {
665
      rtx temp = cmp0;
666
      cmp0 = cmp1;
667
      cmp1 = temp;
668
    }
669
 
670
  return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
671
}
672
 
673
 
674
/* Generate the code to compare two float values.  The return value is
675
   the comparison expression.  */
676
 
677
static rtx
678
gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
679
                      rtx cmp0, /* first operand to compare */
680
                      rtx cmp1 /* second operand to compare */)
681
{
682
  rtx (*gen_fn) (rtx, rtx, rtx);
683
  rtx brtmp;
684
  int reverse_regs, invert;
685
 
686
  switch (test_code)
687
    {
688
    case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
689
    case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
690
    case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
691
    case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
692
    case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
693
    case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
694
    case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
695
    case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
696
    case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
697
    case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
698
    case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
699
    case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
700
    case UNORDERED:
701
      reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
702
    case ORDERED:
703
      reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
704
    default:
705
      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
706
      reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
707
    }
708
 
709
  if (reverse_regs)
710
    {
711
      rtx temp = cmp0;
712
      cmp0 = cmp1;
713
      cmp1 = temp;
714
    }
715
 
716
  brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
717
  emit_insn (gen_fn (brtmp, cmp0, cmp1));
718
 
719
  return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
720
}
721
 
722
 
723
void
724
xtensa_expand_conditional_branch (rtx *operands, enum machine_mode mode)
725
{
726
  enum rtx_code test_code = GET_CODE (operands[0]);
727
  rtx cmp0 = operands[1];
728
  rtx cmp1 = operands[2];
729
  rtx cmp;
730
  int invert;
731
  rtx label1, label2;
732
 
733
  switch (mode)
734
    {
735
    case DFmode:
736
    default:
737
      fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
738
 
739
    case SImode:
740
      invert = FALSE;
741
      cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
742
      break;
743
 
744
    case SFmode:
745
      if (!TARGET_HARD_FLOAT)
746
        fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
747
                                                cmp0, cmp1));
748
      invert = FALSE;
749
      cmp = gen_float_relational (test_code, cmp0, cmp1);
750
      break;
751
    }
752
 
753
  /* Generate the branch.  */
754
 
755
  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
756
  label2 = pc_rtx;
757
 
758
  if (invert)
759
    {
760
      label2 = label1;
761
      label1 = pc_rtx;
762
    }
763
 
764
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
765
                               gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
766
                                                     label1,
767
                                                     label2)));
768
}
769
 
770
 
771
static rtx
772
gen_conditional_move (enum rtx_code code, enum machine_mode mode,
773
                      rtx op0, rtx op1)
774
{
775
  if (mode == SImode)
776
    {
777
      rtx cmp;
778
 
779
      /* Jump optimization calls get_condition() which canonicalizes
780
         comparisons like (GE x <const>) to (GT x <const-1>).
781
         Transform those comparisons back to GE, since that is the
782
         comparison supported in Xtensa.  We shouldn't have to
783
         transform <LE x const> comparisons, because neither
784
         xtensa_expand_conditional_branch() nor get_condition() will
785
         produce them.  */
786
 
787
      if ((code == GT) && (op1 == constm1_rtx))
788
        {
789
          code = GE;
790
          op1 = const0_rtx;
791
        }
792
      cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
793
 
794
      if (boolean_operator (cmp, VOIDmode))
795
        {
796
          /* Swap the operands to make const0 second.  */
797
          if (op0 == const0_rtx)
798
            {
799
              op0 = op1;
800
              op1 = const0_rtx;
801
            }
802
 
803
          /* If not comparing against zero, emit a comparison (subtract).  */
804
          if (op1 != const0_rtx)
805
            {
806
              op0 = expand_binop (SImode, sub_optab, op0, op1,
807
                                  0, 0, OPTAB_LIB_WIDEN);
808
              op1 = const0_rtx;
809
            }
810
        }
811
      else if (branch_operator (cmp, VOIDmode))
812
        {
813
          /* Swap the operands to make const0 second.  */
814
          if (op0 == const0_rtx)
815
            {
816
              op0 = op1;
817
              op1 = const0_rtx;
818
 
819
              switch (code)
820
                {
821
                case LT: code = GE; break;
822
                case GE: code = LT; break;
823
                default: gcc_unreachable ();
824
                }
825
            }
826
 
827
          if (op1 != const0_rtx)
828
            return 0;
829
        }
830
      else
831
        return 0;
832
 
833
      return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
834
    }
835
 
836
  if (TARGET_HARD_FLOAT && mode == SFmode)
837
    return gen_float_relational (code, op0, op1);
838
 
839
  return 0;
840
}
841
 
842
 
843
int
844
xtensa_expand_conditional_move (rtx *operands, int isflt)
845
{
846
  rtx dest = operands[0];
847
  rtx cmp = operands[1];
848
  enum machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
849
  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
850
 
851
  if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
852
                                    XEXP (cmp, 0), XEXP (cmp, 1))))
853
    return 0;
854
 
855
  if (isflt)
856
    gen_fn = (cmp_mode == SImode
857
              ? gen_movsfcc_internal0
858
              : gen_movsfcc_internal1);
859
  else
860
    gen_fn = (cmp_mode == SImode
861
              ? gen_movsicc_internal0
862
              : gen_movsicc_internal1);
863
 
864
  emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
865
  return 1;
866
}
867
 
868
 
869
int
870
xtensa_expand_scc (rtx operands[4], enum machine_mode cmp_mode)
871
{
872
  rtx dest = operands[0];
873
  rtx cmp;
874
  rtx one_tmp, zero_tmp;
875
  rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
876
 
877
  if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
878
                                    operands[2], operands[3])))
879
    return 0;
880
 
881
  one_tmp = gen_reg_rtx (SImode);
882
  zero_tmp = gen_reg_rtx (SImode);
883
  emit_insn (gen_movsi (one_tmp, const_true_rtx));
884
  emit_insn (gen_movsi (zero_tmp, const0_rtx));
885
 
886
  gen_fn = (cmp_mode == SImode
887
            ? gen_movsicc_internal0
888
            : gen_movsicc_internal1);
889
  emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
890
  return 1;
891
}
892
 
893
 
894
/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1].  MODE is
895
   for the output, i.e., the input operands are twice as big as MODE.  */
896
 
897
void
898
xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
899
{
900
  switch (GET_CODE (operands[1]))
901
    {
902
    case REG:
903
      operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
904
      operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
905
      break;
906
 
907
    case MEM:
908
      operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
909
      operands[2] = adjust_address (operands[1], mode, 0);
910
      break;
911
 
912
    case CONST_INT:
913
    case CONST_DOUBLE:
914
      split_double (operands[1], &operands[2], &operands[3]);
915
      break;
916
 
917
    default:
918
      gcc_unreachable ();
919
    }
920
 
921
  switch (GET_CODE (operands[0]))
922
    {
923
    case REG:
924
      operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
925
      operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
926
      break;
927
 
928
    case MEM:
929
      operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
930
      operands[0] = adjust_address (operands[0], mode, 0);
931
      break;
932
 
933
    default:
934
      gcc_unreachable ();
935
    }
936
}
937
 
938
 
939
/* Emit insns to move operands[1] into operands[0].
940
   Return 1 if we have written out everything that needs to be done to
941
   do the move.  Otherwise, return 0 and the caller will emit the move
942
   normally.  */
943
 
944
int
945
xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
946
{
947
  rtx src = operands[1];
948
 
949
  if (CONSTANT_P (src)
950
      && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
951
    {
952
      rtx dst = operands[0];
953
 
954
      if (xtensa_tls_referenced_p (src))
955
        {
956
          rtx addend = NULL;
957
 
958
          if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
959
            {
960
              addend = XEXP (XEXP (src, 0), 1);
961
              src = XEXP (XEXP (src, 0), 0);
962
            }
963
 
964
          src = xtensa_legitimize_tls_address (src);
965
          if (addend)
966
            {
967
              src = gen_rtx_PLUS (mode, src, addend);
968
              src = force_operand (src, dst);
969
            }
970
          emit_move_insn (dst, src);
971
          return 1;
972
        }
973
 
974
      if (! TARGET_CONST16)
975
        {
976
          src = force_const_mem (SImode, src);
977
          operands[1] = src;
978
        }
979
 
980
      /* PC-relative loads are always SImode, and CONST16 is only
981
         supported in the movsi pattern, so add a SUBREG for any other
982
         (smaller) mode.  */
983
 
984
      if (mode != SImode)
985
        {
986
          if (register_operand (dst, mode))
987
            {
988
              emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
989
              return 1;
990
            }
991
          else
992
            {
993
              src = force_reg (SImode, src);
994
              src = gen_lowpart_SUBREG (mode, src);
995
              operands[1] = src;
996
            }
997
        }
998
    }
999
 
1000
  if (!(reload_in_progress | reload_completed)
1001
      && !xtensa_valid_move (mode, operands))
1002
    operands[1] = force_reg (mode, operands[1]);
1003
 
1004
  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1005
 
1006
  /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1007
     instruction won't be recognized after reload, so we remove the
1008
     subreg and adjust mem accordingly.  */
1009
  if (reload_in_progress)
1010
    {
1011
      operands[0] = fixup_subreg_mem (operands[0]);
1012
      operands[1] = fixup_subreg_mem (operands[1]);
1013
    }
1014
  return 0;
1015
}
1016
 
1017
 
1018
static rtx
1019
fixup_subreg_mem (rtx x)
1020
{
1021
  if (GET_CODE (x) == SUBREG
1022
      && GET_CODE (SUBREG_REG (x)) == REG
1023
      && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1024
    {
1025
      rtx temp =
1026
        gen_rtx_SUBREG (GET_MODE (x),
1027
                        reg_equiv_mem [REGNO (SUBREG_REG (x))],
1028
                        SUBREG_BYTE (x));
1029
      x = alter_subreg (&temp);
1030
    }
1031
  return x;
1032
}
1033
 
1034
 
1035
/* Check if an incoming argument in a7 is expected to be used soon and
1036
   if OPND is a register or register pair that includes a7.  If so,
1037
   create a new pseudo and copy a7 into that pseudo at the very
1038
   beginning of the function, followed by the special "set_frame_ptr"
1039
   unspec_volatile insn.  The return value is either the original
1040
   operand, if it is not a7, or the new pseudo containing a copy of
1041
   the incoming argument.  This is necessary because the register
1042
   allocator will ignore conflicts with a7 and may either assign some
1043
   other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1044
   the incoming argument in a7.  By copying the argument out of a7 as
1045
   the very first thing, and then immediately following that with an
1046
   unspec_volatile to keep the scheduler away, we should avoid any
1047
   problems.  Putting the set_frame_ptr insn at the beginning, with
1048
   only the a7 copy before it, also makes it easier for the prologue
1049
   expander to initialize the frame pointer after the a7 copy and to
1050
   fix up the a7 copy to use the stack pointer instead of the frame
1051
   pointer.  */
1052
 
1053
rtx
1054
xtensa_copy_incoming_a7 (rtx opnd)
1055
{
1056
  rtx entry_insns = 0;
1057
  rtx reg, tmp;
1058
  enum machine_mode mode;
1059
 
1060
  if (!cfun->machine->need_a7_copy)
1061
    return opnd;
1062
 
1063
  /* This function should never be called again once a7 has been copied.  */
1064
  gcc_assert (!cfun->machine->set_frame_ptr_insn);
1065
 
1066
  mode = GET_MODE (opnd);
1067
 
1068
  /* The operand using a7 may come in a later instruction, so just return
1069
     the original operand if it doesn't use a7.  */
1070
  reg = opnd;
1071
  if (GET_CODE (reg) == SUBREG)
1072
    {
1073
      gcc_assert (SUBREG_BYTE (reg) == 0);
1074
      reg = SUBREG_REG (reg);
1075
    }
1076
  if (GET_CODE (reg) != REG
1077
      || REGNO (reg) > A7_REG
1078
      || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1079
    return opnd;
1080
 
1081
  /* 1-word args will always be in a7; 2-word args in a6/a7.  */
1082
  gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG);
1083
 
1084
  cfun->machine->need_a7_copy = false;
1085
 
1086
  /* Copy a7 to a new pseudo at the function entry.  Use gen_raw_REG to
1087
     create the REG for a7 so that hard_frame_pointer_rtx is not used.  */
1088
 
1089
  start_sequence ();
1090
  tmp = gen_reg_rtx (mode);
1091
 
1092
  switch (mode)
1093
    {
1094
    case DFmode:
1095
    case DImode:
1096
      /* Copy the value out of A7 here but keep the first word in A6 until
1097
         after the set_frame_ptr insn.  Otherwise, the register allocator
1098
         may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1099
         value.  */
1100
      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1101
                                     gen_raw_REG (SImode, A7_REG)));
1102
      break;
1103
    case SFmode:
1104
      emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1105
      break;
1106
    case SImode:
1107
      emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1108
      break;
1109
    case HImode:
1110
      emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1111
      break;
1112
    case QImode:
1113
      emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1114
      break;
1115
    default:
1116
      gcc_unreachable ();
1117
    }
1118
 
1119
  cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1120
 
1121
  /* For DF and DI mode arguments, copy the incoming value in A6 now.  */
1122
  if (mode == DFmode || mode == DImode)
1123
    emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1124
                                   gen_rtx_REG (SImode, A7_REG - 1)));
1125
  entry_insns = get_insns ();
1126
  end_sequence ();
1127
 
1128
  if (cfun->machine->vararg_a7)
1129
    {
1130
      /* This is called from within builtin_saveregs, which will insert the
1131
         saveregs code at the function entry, ahead of anything placed at
1132
         the function entry now.  Instead, save the sequence to be inserted
1133
         at the beginning of the saveregs code.  */
1134
      cfun->machine->vararg_a7_copy = entry_insns;
1135
    }
1136
  else
1137
    {
1138
      /* Put entry_insns after the NOTE that starts the function.  If
1139
         this is inside a start_sequence, make the outer-level insn
1140
         chain current, so the code is placed at the start of the
1141
         function.  */
1142
      push_topmost_sequence ();
1143
      /* Do not use entry_of_function() here.  This is called from within
1144
         expand_function_start, when the CFG still holds GIMPLE.  */
1145
      emit_insn_after (entry_insns, get_insns ());
1146
      pop_topmost_sequence ();
1147
    }
1148
 
1149
  return tmp;
1150
}
1151
 
1152
 
1153
/* Try to expand a block move operation to a sequence of RTL move
1154
   instructions.  If not optimizing, or if the block size is not a
1155
   constant, or if the block is too large, the expansion fails and GCC
1156
   falls back to calling memcpy().
1157
 
1158
   operands[0] is the destination
1159
   operands[1] is the source
1160
   operands[2] is the length
1161
   operands[3] is the alignment */
1162
 
1163
int
1164
xtensa_expand_block_move (rtx *operands)
1165
{
1166
  static const enum machine_mode mode_from_align[] =
1167
  {
1168
    VOIDmode, QImode, HImode, VOIDmode, SImode,
1169
  };
1170
 
1171
  rtx dst_mem = operands[0];
1172
  rtx src_mem = operands[1];
1173
  HOST_WIDE_INT bytes, align;
1174
  int num_pieces, move_ratio;
1175
  rtx temp[2];
1176
  enum machine_mode mode[2];
1177
  int amount[2];
1178
  bool active[2];
1179
  int phase = 0;
1180
  int next;
1181
  int offset_ld = 0;
1182
  int offset_st = 0;
1183
  rtx x;
1184
 
1185
  /* If this is not a fixed size move, just call memcpy.  */
1186
  if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1187
    return 0;
1188
 
1189
  bytes = INTVAL (operands[2]);
1190
  align = INTVAL (operands[3]);
1191
 
1192
  /* Anything to move?  */
1193
  if (bytes <= 0)
1194
    return 0;
1195
 
1196
  if (align > MOVE_MAX)
1197
    align = MOVE_MAX;
1198
 
1199
  /* Decide whether to expand inline based on the optimization level.  */
1200
  move_ratio = 4;
1201
  if (optimize > 2)
1202
    move_ratio = LARGEST_MOVE_RATIO;
1203
  num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway.  */
1204
  if (num_pieces > move_ratio)
1205
    return 0;
1206
 
1207
  x = XEXP (dst_mem, 0);
1208
  if (!REG_P (x))
1209
    {
1210
      x = force_reg (Pmode, x);
1211
      dst_mem = replace_equiv_address (dst_mem, x);
1212
    }
1213
 
1214
  x = XEXP (src_mem, 0);
1215
  if (!REG_P (x))
1216
    {
1217
      x = force_reg (Pmode, x);
1218
      src_mem = replace_equiv_address (src_mem, x);
1219
    }
1220
 
1221
  active[0] = active[1] = false;
1222
 
1223
  do
1224
    {
1225
      next = phase;
1226
      phase ^= 1;
1227
 
1228
      if (bytes > 0)
1229
        {
1230
          int next_amount;
1231
 
1232
          next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1233
          next_amount = MIN (next_amount, align);
1234
 
1235
          amount[next] = next_amount;
1236
          mode[next] = mode_from_align[next_amount];
1237
          temp[next] = gen_reg_rtx (mode[next]);
1238
 
1239
          x = adjust_address (src_mem, mode[next], offset_ld);
1240
          emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
1241
 
1242
          offset_ld += next_amount;
1243
          bytes -= next_amount;
1244
          active[next] = true;
1245
        }
1246
 
1247
      if (active[phase])
1248
        {
1249
          active[phase] = false;
1250
 
1251
          x = adjust_address (dst_mem, mode[phase], offset_st);
1252
          emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
1253
 
1254
          offset_st += amount[phase];
1255
        }
1256
    }
1257
  while (active[next]);
1258
 
1259
  return 1;
1260
}
1261
 
1262
 
1263
void
1264
xtensa_expand_nonlocal_goto (rtx *operands)
1265
{
1266
  rtx goto_handler = operands[1];
1267
  rtx containing_fp = operands[3];
1268
 
1269
  /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1270
     is too big to generate in-line.  */
1271
 
1272
  if (GET_CODE (containing_fp) != REG)
1273
    containing_fp = force_reg (Pmode, containing_fp);
1274
 
1275
  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1276
                     0, VOIDmode, 2,
1277
                     containing_fp, Pmode,
1278
                     goto_handler, Pmode);
1279
}
1280
 
1281
 
1282
static struct machine_function *
1283
xtensa_init_machine_status (void)
1284
{
1285
  return GGC_CNEW (struct machine_function);
1286
}
1287
 
1288
 
1289
/* Shift VAL of mode MODE left by COUNT bits.  */
1290
 
1291
static inline rtx
1292
xtensa_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
1293
{
1294
  val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1295
                             NULL_RTX, 1, OPTAB_DIRECT);
1296
  return expand_simple_binop (SImode, ASHIFT, val, count,
1297
                              NULL_RTX, 1, OPTAB_DIRECT);
1298
}
1299
 
1300
 
1301
/* Structure to hold the initial parameters for a compare_and_swap operation
1302
   in HImode and QImode.  */
1303
 
1304
struct alignment_context
1305
{
1306
  rtx memsi;      /* SI aligned memory location.  */
1307
  rtx shift;      /* Bit offset with regard to lsb.  */
1308
  rtx modemask;   /* Mask of the HQImode shifted by SHIFT bits.  */
1309
  rtx modemaski;  /* ~modemask */
1310
};
1311
 
1312
 
1313
/* Initialize structure AC for word access to HI and QI mode memory.  */
1314
 
1315
static void
1316
init_alignment_context (struct alignment_context *ac, rtx mem)
1317
{
1318
  enum machine_mode mode = GET_MODE (mem);
1319
  rtx byteoffset = NULL_RTX;
1320
  bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1321
 
1322
  if (aligned)
1323
    ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned.  */
1324
  else
1325
    {
1326
      /* Alignment is unknown.  */
1327
      rtx addr, align;
1328
 
1329
      /* Force the address into a register.  */
1330
      addr = force_reg (Pmode, XEXP (mem, 0));
1331
 
1332
      /* Align it to SImode.  */
1333
      align = expand_simple_binop (Pmode, AND, addr,
1334
                                   GEN_INT (-GET_MODE_SIZE (SImode)),
1335
                                   NULL_RTX, 1, OPTAB_DIRECT);
1336
      /* Generate MEM.  */
1337
      ac->memsi = gen_rtx_MEM (SImode, align);
1338
      MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1339
      set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1340
      set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1341
 
1342
      byteoffset = expand_simple_binop (Pmode, AND, addr,
1343
                                        GEN_INT (GET_MODE_SIZE (SImode) - 1),
1344
                                        NULL_RTX, 1, OPTAB_DIRECT);
1345
    }
1346
 
1347
  /* Calculate shiftcount.  */
1348
  if (TARGET_BIG_ENDIAN)
1349
    {
1350
      ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1351
      if (!aligned)
1352
        ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1353
                                         NULL_RTX, 1, OPTAB_DIRECT);
1354
    }
1355
  else
1356
    {
1357
      if (aligned)
1358
        ac->shift = NULL_RTX;
1359
      else
1360
        ac->shift = byteoffset;
1361
    }
1362
 
1363
  if (ac->shift != NULL_RTX)
1364
    {
1365
      /* Shift is the byte count, but we need the bitcount.  */
1366
      ac->shift = expand_simple_binop (SImode, MULT, ac->shift,
1367
                                       GEN_INT (BITS_PER_UNIT),
1368
                                       NULL_RTX, 1, OPTAB_DIRECT);
1369
      ac->modemask = expand_simple_binop (SImode, ASHIFT,
1370
                                          GEN_INT (GET_MODE_MASK (mode)),
1371
                                          ac->shift,
1372
                                          NULL_RTX, 1, OPTAB_DIRECT);
1373
    }
1374
  else
1375
    ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1376
 
1377
  ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1378
}
1379
 
1380
 
1381
/* Expand an atomic compare and swap operation for HImode and QImode.
1382
   MEM is the memory location, CMP the old value to compare MEM with
1383
   and NEW_RTX the value to set if CMP == MEM.  */
1384
 
1385
void
1386
xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1387
{
1388
  enum machine_mode mode = GET_MODE (mem);
1389
  struct alignment_context ac;
1390
  rtx tmp, cmpv, newv, val;
1391
  rtx oldval = gen_reg_rtx (SImode);
1392
  rtx res = gen_reg_rtx (SImode);
1393
  rtx csloop = gen_label_rtx ();
1394
  rtx csend = gen_label_rtx ();
1395
 
1396
  init_alignment_context (&ac, mem);
1397
 
1398
  if (ac.shift != NULL_RTX)
1399
    {
1400
      cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1401
      new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1402
    }
1403
 
1404
  /* Load the surrounding word into VAL with the MEM value masked out.  */
1405
  val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1406
                                                ac.modemaski, NULL_RTX, 1,
1407
                                                OPTAB_DIRECT));
1408
  emit_label (csloop);
1409
 
1410
  /* Patch CMP and NEW_RTX into VAL at correct position.  */
1411
  cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1412
                                                 NULL_RTX, 1, OPTAB_DIRECT));
1413
  newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1414
                                                 NULL_RTX, 1, OPTAB_DIRECT));
1415
 
1416
  /* Jump to end if we're done.  */
1417
  emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1418
  emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1419
 
1420
  /* Check for changes outside mode.  */
1421
  emit_move_insn (oldval, val);
1422
  tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1423
                             val, 1, OPTAB_DIRECT);
1424
  if (tmp != val)
1425
    emit_move_insn (val, tmp);
1426
 
1427
  /* Loop internal if so.  */
1428
  emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1429
 
1430
  emit_label (csend);
1431
 
1432
  /* Return the correct part of the bitfield.  */
1433
  convert_move (target,
1434
                (ac.shift == NULL_RTX ? res
1435
                 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1436
                                        NULL_RTX, 1, OPTAB_DIRECT)),
1437
                1);
1438
}
1439
 
1440
 
1441
/* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1442
   the default expansion works fine for SImode).  MEM is the memory location
1443
   and VAL the value to play with.  If AFTER is true then store the value
1444
   MEM holds after the operation, if AFTER is false then store the value MEM
1445
   holds before the operation.  If TARGET is zero then discard that value, else
1446
   store it to TARGET.  */
1447
 
1448
void
1449
xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1450
                      bool after)
1451
{
1452
  enum machine_mode mode = GET_MODE (mem);
1453
  struct alignment_context ac;
1454
  rtx csloop = gen_label_rtx ();
1455
  rtx cmp, tmp;
1456
  rtx old = gen_reg_rtx (SImode);
1457
  rtx new_rtx = gen_reg_rtx (SImode);
1458
  rtx orig = NULL_RTX;
1459
 
1460
  init_alignment_context (&ac, mem);
1461
 
1462
  /* Prepare values before the compare-and-swap loop.  */
1463
  if (ac.shift != NULL_RTX)
1464
    val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1465
  switch (code)
1466
    {
1467
    case PLUS:
1468
    case MINUS:
1469
      orig = gen_reg_rtx (SImode);
1470
      convert_move (orig, val, 1);
1471
      break;
1472
 
1473
    case SET:
1474
    case IOR:
1475
    case XOR:
1476
      break;
1477
 
1478
    case MULT: /* NAND */
1479
    case AND:
1480
      /* val = "11..1<val>11..1" */
1481
      val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1482
                                 NULL_RTX, 1, OPTAB_DIRECT);
1483
      break;
1484
 
1485
    default:
1486
      gcc_unreachable ();
1487
    }
1488
 
1489
  /* Load full word.  Subsequent loads are performed by S32C1I.  */
1490
  cmp = force_reg (SImode, ac.memsi);
1491
 
1492
  emit_label (csloop);
1493
  emit_move_insn (old, cmp);
1494
 
1495
  switch (code)
1496
    {
1497
    case PLUS:
1498
    case MINUS:
1499
      val = expand_simple_binop (SImode, code, old, orig,
1500
                                 NULL_RTX, 1, OPTAB_DIRECT);
1501
      val = expand_simple_binop (SImode, AND, val, ac.modemask,
1502
                                 NULL_RTX, 1, OPTAB_DIRECT);
1503
      /* FALLTHRU */
1504
    case SET:
1505
      tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1506
                                 NULL_RTX, 1, OPTAB_DIRECT);
1507
      tmp = expand_simple_binop (SImode, IOR, tmp, val,
1508
                                 new_rtx, 1, OPTAB_DIRECT);
1509
      break;
1510
 
1511
    case AND:
1512
    case IOR:
1513
    case XOR:
1514
      tmp = expand_simple_binop (SImode, code, old, val,
1515
                                 new_rtx, 1, OPTAB_DIRECT);
1516
      break;
1517
 
1518
    case MULT: /* NAND */
1519
      tmp = expand_simple_binop (SImode, XOR, old, ac.modemask,
1520
                                 NULL_RTX, 1, OPTAB_DIRECT);
1521
      tmp = expand_simple_binop (SImode, AND, tmp, val,
1522
                                 new_rtx, 1, OPTAB_DIRECT);
1523
      break;
1524
 
1525
    default:
1526
      gcc_unreachable ();
1527
    }
1528
 
1529
  if (tmp != new_rtx)
1530
    emit_move_insn (new_rtx, tmp);
1531
  emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1532
  emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1533
 
1534
  if (target)
1535
    {
1536
      tmp = (after ? new_rtx : cmp);
1537
      convert_move (target,
1538
                    (ac.shift == NULL_RTX ? tmp
1539
                     : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1540
                                            NULL_RTX, 1, OPTAB_DIRECT)),
1541
                    1);
1542
    }
1543
}
1544
 
1545
 
1546
void
1547
xtensa_setup_frame_addresses (void)
1548
{
1549
  /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true.  */
1550
  cfun->machine->accesses_prev_frame = 1;
1551
 
1552
  emit_library_call
1553
    (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1554
     0, VOIDmode, 0);
1555
}
1556
 
1557
 
1558
/* Emit the assembly for the end of a zero-cost loop.  Normally we just emit
1559
   a comment showing where the end of the loop is.  However, if there is a
1560
   label or a branch at the end of the loop then we need to place a nop
1561
   there.  If the loop ends with a label we need the nop so that branches
1562
   targeting that label will target the nop (and thus remain in the loop),
1563
   instead of targeting the instruction after the loop (and thus exiting
1564
   the loop).  If the loop ends with a branch, we need the nop in case the
1565
   branch is targeting a location inside the loop.  When the branch
1566
   executes it will cause the loop count to be decremented even if it is
1567
   taken (because it is the last instruction in the loop), so we need to
1568
   nop after the branch to prevent the loop count from being decremented
1569
   when the branch is taken.  */
1570
 
1571
void
1572
xtensa_emit_loop_end (rtx insn, rtx *operands)
1573
{
1574
  char done = 0;
1575
 
1576
  for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1577
    {
1578
      switch (GET_CODE (insn))
1579
        {
1580
        case NOTE:
1581
        case BARRIER:
1582
          break;
1583
 
1584
        case CODE_LABEL:
1585
          output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1586
          done = 1;
1587
          break;
1588
 
1589
        default:
1590
          {
1591
            rtx body = PATTERN (insn);
1592
 
1593
            if (GET_CODE (body) == JUMP_INSN)
1594
              {
1595
                output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1596
                done = 1;
1597
              }
1598
            else if ((GET_CODE (body) != USE)
1599
                     && (GET_CODE (body) != CLOBBER))
1600
              done = 1;
1601
          }
1602
          break;
1603
        }
1604
    }
1605
 
1606
  output_asm_insn ("# loop end for %0", operands);
1607
}
1608
 
1609
 
1610
char *
1611
xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1612
{
1613
  static char result[64];
1614
  enum rtx_code code;
1615
  const char *op;
1616
 
1617
  code = GET_CODE (operands[3]);
1618
  switch (code)
1619
    {
1620
    case EQ:    op = inverted ? "ne" : "eq"; break;
1621
    case NE:    op = inverted ? "eq" : "ne"; break;
1622
    case LT:    op = inverted ? "ge" : "lt"; break;
1623
    case GE:    op = inverted ? "lt" : "ge"; break;
1624
    case LTU:   op = inverted ? "geu" : "ltu"; break;
1625
    case GEU:   op = inverted ? "ltu" : "geu"; break;
1626
    default:    gcc_unreachable ();
1627
    }
1628
 
1629
  if (immed)
1630
    {
1631
      if (INTVAL (operands[1]) == 0)
1632
        sprintf (result, "b%sz%s\t%%0, %%2", op,
1633
                 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1634
      else
1635
        sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1636
    }
1637
  else
1638
    sprintf (result, "b%s\t%%0, %%1, %%2", op);
1639
 
1640
  return result;
1641
}
1642
 
1643
 
1644
char *
1645
xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1646
{
1647
  static char result[64];
1648
  const char *op;
1649
 
1650
  switch (GET_CODE (operands[3]))
1651
    {
1652
    case EQ:    op = inverted ? "bs" : "bc"; break;
1653
    case NE:    op = inverted ? "bc" : "bs"; break;
1654
    default:    gcc_unreachable ();
1655
    }
1656
 
1657
  if (immed)
1658
    {
1659
      unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1660
      operands[1] = GEN_INT (bitnum);
1661
      sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1662
    }
1663
  else
1664
    sprintf (result, "b%s\t%%0, %%1, %%2", op);
1665
 
1666
  return result;
1667
}
1668
 
1669
 
1670
char *
1671
xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1672
{
1673
  static char result[64];
1674
  enum rtx_code code;
1675
  const char *op;
1676
 
1677
  code = GET_CODE (operands[4]);
1678
  if (isbool)
1679
    {
1680
      switch (code)
1681
        {
1682
        case EQ:        op = inverted ? "t" : "f"; break;
1683
        case NE:        op = inverted ? "f" : "t"; break;
1684
        default:        gcc_unreachable ();
1685
        }
1686
    }
1687
  else
1688
    {
1689
      switch (code)
1690
        {
1691
        case EQ:        op = inverted ? "nez" : "eqz"; break;
1692
        case NE:        op = inverted ? "eqz" : "nez"; break;
1693
        case LT:        op = inverted ? "gez" : "ltz"; break;
1694
        case GE:        op = inverted ? "ltz" : "gez"; break;
1695
        default:        gcc_unreachable ();
1696
        }
1697
    }
1698
 
1699
  sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1700
           op, isfp ? ".s" : "", inverted ? 3 : 2);
1701
  return result;
1702
}
1703
 
1704
 
1705
char *
1706
xtensa_emit_call (int callop, rtx *operands)
1707
{
1708
  static char result[64];
1709
  rtx tgt = operands[callop];
1710
 
1711
  if (GET_CODE (tgt) == CONST_INT)
1712
    sprintf (result, "call8\t0x%lx", INTVAL (tgt));
1713
  else if (register_operand (tgt, VOIDmode))
1714
    sprintf (result, "callx8\t%%%d", callop);
1715
  else
1716
    sprintf (result, "call8\t%%%d", callop);
1717
 
1718
  return result;
1719
}
1720
 
1721
 
1722
bool
1723
xtensa_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
1724
{
1725
  /* Allow constant pool addresses.  */
1726
  if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1727
      && ! TARGET_CONST16 && constantpool_address_p (addr)
1728
      && ! xtensa_tls_referenced_p (addr))
1729
    return true;
1730
 
1731
  while (GET_CODE (addr) == SUBREG)
1732
    addr = SUBREG_REG (addr);
1733
 
1734
  /* Allow base registers.  */
1735
  if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1736
    return true;
1737
 
1738
  /* Check for "register + offset" addressing.  */
1739
  if (GET_CODE (addr) == PLUS)
1740
    {
1741
      rtx xplus0 = XEXP (addr, 0);
1742
      rtx xplus1 = XEXP (addr, 1);
1743
      enum rtx_code code0;
1744
      enum rtx_code code1;
1745
 
1746
      while (GET_CODE (xplus0) == SUBREG)
1747
        xplus0 = SUBREG_REG (xplus0);
1748
      code0 = GET_CODE (xplus0);
1749
 
1750
      while (GET_CODE (xplus1) == SUBREG)
1751
        xplus1 = SUBREG_REG (xplus1);
1752
      code1 = GET_CODE (xplus1);
1753
 
1754
      /* Swap operands if necessary so the register is first.  */
1755
      if (code0 != REG && code1 == REG)
1756
        {
1757
          xplus0 = XEXP (addr, 1);
1758
          xplus1 = XEXP (addr, 0);
1759
          code0 = GET_CODE (xplus0);
1760
          code1 = GET_CODE (xplus1);
1761
        }
1762
 
1763
      if (code0 == REG && BASE_REG_P (xplus0, strict)
1764
          && code1 == CONST_INT
1765
          && xtensa_mem_offset (INTVAL (xplus1), mode))
1766
        return true;
1767
    }
1768
 
1769
  return false;
1770
}
1771
 
1772
 
1773
/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
1774
 
1775
static GTY(()) rtx xtensa_tls_module_base_symbol;
1776
 
1777
static rtx
1778
xtensa_tls_module_base (void)
1779
{
1780
  if (! xtensa_tls_module_base_symbol)
1781
    {
1782
      xtensa_tls_module_base_symbol =
1783
        gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1784
      SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1785
        |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1786
    }
1787
 
1788
  return xtensa_tls_module_base_symbol;
1789
}
1790
 
1791
 
1792
static rtx
1793
xtensa_call_tls_desc (rtx sym, rtx *retp)
1794
{
1795
  rtx fn, arg, a10, call_insn, insns;
1796
 
1797
  start_sequence ();
1798
  fn = gen_reg_rtx (Pmode);
1799
  arg = gen_reg_rtx (Pmode);
1800
  a10 = gen_rtx_REG (Pmode, 10);
1801
 
1802
  emit_insn (gen_tls_func (fn, sym));
1803
  emit_insn (gen_tls_arg (arg, sym));
1804
  emit_move_insn (a10, arg);
1805
  call_insn = emit_call_insn (gen_tls_call (a10, fn, sym, const1_rtx));
1806
  CALL_INSN_FUNCTION_USAGE (call_insn)
1807
    = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, a10),
1808
                         CALL_INSN_FUNCTION_USAGE (call_insn));
1809
  insns = get_insns ();
1810
  end_sequence ();
1811
 
1812
  *retp = a10;
1813
  return insns;
1814
}
1815
 
1816
 
1817
static rtx
1818
xtensa_legitimize_tls_address (rtx x)
1819
{
1820
  unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1821
  rtx dest, tp, ret, modbase, base, addend, insns;
1822
 
1823
  dest = gen_reg_rtx (Pmode);
1824
  switch (model)
1825
    {
1826
    case TLS_MODEL_GLOBAL_DYNAMIC:
1827
      insns = xtensa_call_tls_desc (x, &ret);
1828
      emit_libcall_block (insns, dest, ret, x);
1829
      break;
1830
 
1831
    case TLS_MODEL_LOCAL_DYNAMIC:
1832
      base = gen_reg_rtx (Pmode);
1833
      modbase = xtensa_tls_module_base ();
1834
      insns = xtensa_call_tls_desc (modbase, &ret);
1835
      emit_libcall_block (insns, base, ret, modbase);
1836
      addend = force_reg (SImode, gen_sym_DTPOFF (x));
1837
      emit_insn (gen_addsi3 (dest, base, addend));
1838
      break;
1839
 
1840
    case TLS_MODEL_INITIAL_EXEC:
1841
    case TLS_MODEL_LOCAL_EXEC:
1842
      tp = gen_reg_rtx (SImode);
1843
      emit_insn (gen_load_tp (tp));
1844
      addend = force_reg (SImode, gen_sym_TPOFF (x));
1845
      emit_insn (gen_addsi3 (dest, tp, addend));
1846
      break;
1847
 
1848
    default:
1849
      gcc_unreachable ();
1850
    }
1851
 
1852
  return dest;
1853
}
1854
 
1855
 
1856
rtx
1857
xtensa_legitimize_address (rtx x,
1858
                           rtx oldx ATTRIBUTE_UNUSED,
1859
                           enum machine_mode mode)
1860
{
1861
  if (xtensa_tls_symbol_p (x))
1862
    return xtensa_legitimize_tls_address (x);
1863
 
1864
  if (GET_CODE (x) == PLUS)
1865
    {
1866
      rtx plus0 = XEXP (x, 0);
1867
      rtx plus1 = XEXP (x, 1);
1868
 
1869
      if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1870
        {
1871
          plus0 = XEXP (x, 1);
1872
          plus1 = XEXP (x, 0);
1873
        }
1874
 
1875
      /* Try to split up the offset to use an ADDMI instruction.  */
1876
      if (GET_CODE (plus0) == REG
1877
          && GET_CODE (plus1) == CONST_INT
1878
          && !xtensa_mem_offset (INTVAL (plus1), mode)
1879
          && !xtensa_simm8 (INTVAL (plus1))
1880
          && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1881
          && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1882
        {
1883
          rtx temp = gen_reg_rtx (Pmode);
1884
          rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1885
          emit_insn (gen_rtx_SET (Pmode, temp,
1886
                                  gen_rtx_PLUS (Pmode, plus0, addmi_offset)));
1887
          return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1888
        }
1889
    }
1890
 
1891
  return x;
1892
}
1893
 
1894
 
1895
/* Helper for xtensa_tls_referenced_p.  */
1896
 
1897
static int
1898
xtensa_tls_referenced_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1899
{
1900
  if (GET_CODE (*x) == SYMBOL_REF)
1901
    return SYMBOL_REF_TLS_MODEL (*x) != 0;
1902
 
1903
  /* Ignore TLS references that have already been legitimized.  */
1904
  if (GET_CODE (*x) == UNSPEC)
1905
    {
1906
      switch (XINT (*x, 1))
1907
        {
1908
        case UNSPEC_TPOFF:
1909
        case UNSPEC_DTPOFF:
1910
        case UNSPEC_TLS_FUNC:
1911
        case UNSPEC_TLS_ARG:
1912
        case UNSPEC_TLS_CALL:
1913
          return -1;
1914
        default:
1915
          break;
1916
        }
1917
    }
1918
 
1919
  return 0;
1920
}
1921
 
1922
 
1923
/* Return TRUE if X contains any TLS symbol references.  */
1924
 
1925
bool
1926
xtensa_tls_referenced_p (rtx x)
1927
{
1928
  if (! TARGET_HAVE_TLS)
1929
    return false;
1930
 
1931
  return for_each_rtx (&x, xtensa_tls_referenced_p_1, NULL);
1932
}
1933
 
1934
 
1935
/* Return the debugger register number to use for 'regno'.  */
1936
 
1937
int
1938
xtensa_dbx_register_number (int regno)
1939
{
1940
  int first = -1;
1941
 
1942
  if (GP_REG_P (regno))
1943
    {
1944
      regno -= GP_REG_FIRST;
1945
      first = 0;
1946
    }
1947
  else if (BR_REG_P (regno))
1948
    {
1949
      regno -= BR_REG_FIRST;
1950
      first = 16;
1951
    }
1952
  else if (FP_REG_P (regno))
1953
    {
1954
      regno -= FP_REG_FIRST;
1955
      first = 48;
1956
    }
1957
  else if (ACC_REG_P (regno))
1958
    {
1959
      first = 0x200;    /* Start of Xtensa special registers.  */
1960
      regno = 16;       /* ACCLO is special register 16.  */
1961
    }
1962
 
1963
  /* When optimizing, we sometimes get asked about pseudo-registers
1964
     that don't represent hard registers.  Return 0 for these.  */
1965
  if (first == -1)
1966
    return 0;
1967
 
1968
  return first + regno;
1969
}
1970
 
1971
 
1972
/* Argument support functions.  */
1973
 
1974
/* Initialize CUMULATIVE_ARGS for a function.  */
1975
 
1976
void
1977
init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
1978
{
1979
  cum->arg_words = 0;
1980
  cum->incoming = incoming;
1981
}
1982
 
1983
 
1984
/* Advance the argument to the next argument position.  */
1985
 
1986
void
1987
function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
1988
{
1989
  int words, max;
1990
  int *arg_words;
1991
 
1992
  arg_words = &cum->arg_words;
1993
  max = MAX_ARGS_IN_REGISTERS;
1994
 
1995
  words = (((mode != BLKmode)
1996
            ? (int) GET_MODE_SIZE (mode)
1997
            : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1998
 
1999
  if (*arg_words < max
2000
      && (targetm.calls.must_pass_in_stack (mode, type)
2001
          || *arg_words + words > max))
2002
    *arg_words = max;
2003
 
2004
  *arg_words += words;
2005
}
2006
 
2007
 
2008
/* Return an RTL expression containing the register for the given mode,
2009
   or 0 if the argument is to be passed on the stack.  INCOMING_P is nonzero
2010
   if this is an incoming argument to the current function.  */
2011
 
2012
rtx
2013
function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2014
              int incoming_p)
2015
{
2016
  int regbase, words, max;
2017
  int *arg_words;
2018
  int regno;
2019
 
2020
  arg_words = &cum->arg_words;
2021
  regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2022
  max = MAX_ARGS_IN_REGISTERS;
2023
 
2024
  words = (((mode != BLKmode)
2025
            ? (int) GET_MODE_SIZE (mode)
2026
            : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2027
 
2028
  if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
2029
    {
2030
      int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
2031
      *arg_words = (*arg_words + align - 1) & -align;
2032
    }
2033
 
2034
  if (*arg_words + words > max)
2035
    return (rtx)0;
2036
 
2037
  regno = regbase + *arg_words;
2038
 
2039
  if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2040
    cfun->machine->need_a7_copy = true;
2041
 
2042
  return gen_rtx_REG (mode, regno);
2043
}
2044
 
2045
 
2046
int
2047
function_arg_boundary (enum machine_mode mode, tree type)
2048
{
2049
  unsigned int alignment;
2050
 
2051
  alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2052
  if (alignment < PARM_BOUNDARY)
2053
    alignment = PARM_BOUNDARY;
2054
  if (alignment > STACK_BOUNDARY)
2055
    alignment = STACK_BOUNDARY;
2056
  return alignment;
2057
}
2058
 
2059
 
2060
static bool
2061
xtensa_return_in_msb (const_tree valtype)
2062
{
2063
  return (TARGET_BIG_ENDIAN
2064
          && AGGREGATE_TYPE_P (valtype)
2065
          && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2066
}
2067
 
2068
 
2069
void
2070
override_options (void)
2071
{
2072
  int regno;
2073
  enum machine_mode mode;
2074
 
2075
  if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2076
    error ("boolean registers required for the floating-point option");
2077
 
2078
  /* Set up array giving whether a given register can hold a given mode.  */
2079
  for (mode = VOIDmode;
2080
       mode != MAX_MACHINE_MODE;
2081
       mode = (enum machine_mode) ((int) mode + 1))
2082
    {
2083
      int size = GET_MODE_SIZE (mode);
2084
      enum mode_class mclass = GET_MODE_CLASS (mode);
2085
 
2086
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2087
        {
2088
          int temp;
2089
 
2090
          if (ACC_REG_P (regno))
2091
            temp = (TARGET_MAC16
2092
                    && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2093
          else if (GP_REG_P (regno))
2094
            temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2095
          else if (FP_REG_P (regno))
2096
            temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2097
          else if (BR_REG_P (regno))
2098
            temp = (TARGET_BOOLEANS && (mode == CCmode));
2099
          else
2100
            temp = FALSE;
2101
 
2102
          xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
2103
        }
2104
    }
2105
 
2106
  init_machine_status = xtensa_init_machine_status;
2107
 
2108
  /* Check PIC settings.  PIC is only supported when using L32R
2109
     instructions, and some targets need to always use PIC.  */
2110
  if (flag_pic && TARGET_CONST16)
2111
    error ("-f%s is not supported with CONST16 instructions",
2112
           (flag_pic > 1 ? "PIC" : "pic"));
2113
  else if (XTENSA_ALWAYS_PIC)
2114
    {
2115
      if (TARGET_CONST16)
2116
        error ("PIC is required but not supported with CONST16 instructions");
2117
      flag_pic = 1;
2118
    }
2119
  /* There's no need for -fPIC (as opposed to -fpic) on Xtensa.  */
2120
  if (flag_pic > 1)
2121
    flag_pic = 1;
2122
  if (flag_pic && !flag_pie)
2123
    flag_shlib = 1;
2124
 
2125
  /* Hot/cold partitioning does not work on this architecture, because of
2126
     constant pools (the load instruction cannot necessarily reach that far).
2127
     Therefore disable it on this architecture.  */
2128
  if (flag_reorder_blocks_and_partition)
2129
    {
2130
      flag_reorder_blocks_and_partition = 0;
2131
      flag_reorder_blocks = 1;
2132
    }
2133
}
2134
 
2135
 
2136
/* A C compound statement to output to stdio stream STREAM the
2137
   assembler syntax for an instruction operand X.  X is an RTL
2138
   expression.
2139
 
2140
   CODE is a value that can be used to specify one of several ways
2141
   of printing the operand.  It is used when identical operands
2142
   must be printed differently depending on the context.  CODE
2143
   comes from the '%' specification that was used to request
2144
   printing of the operand.  If the specification was just '%DIGIT'
2145
   then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2146
   is the ASCII code for LTR.
2147
 
2148
   If X is a register, this macro should print the register's name.
2149
   The names can be found in an array 'reg_names' whose type is
2150
   'char *[]'.  'reg_names' is initialized from 'REGISTER_NAMES'.
2151
 
2152
   When the machine description has a specification '%PUNCT' (a '%'
2153
   followed by a punctuation character), this macro is called with
2154
   a null pointer for X and the punctuation character for CODE.
2155
 
2156
   'a', 'c', 'l', and 'n' are reserved.
2157
 
2158
   The Xtensa specific codes are:
2159
 
2160
   'd'  CONST_INT, print as signed decimal
2161
   'x'  CONST_INT, print as signed hexadecimal
2162
   'K'  CONST_INT, print number of bits in mask for EXTUI
2163
   'R'  CONST_INT, print (X & 0x1f)
2164
   'L'  CONST_INT, print ((32 - X) & 0x1f)
2165
   'D'  REG, print second register of double-word register operand
2166
   'N'  MEM, print address of next word following a memory operand
2167
   'v'  MEM, if memory reference is volatile, output a MEMW before it
2168
   't'  any constant, add "@h" suffix for top 16 bits
2169
   'b'  any constant, add "@l" suffix for bottom 16 bits
2170
*/
2171
 
2172
static void
2173
printx (FILE *file, signed int val)
2174
{
2175
  /* Print a hexadecimal value in a nice way.  */
2176
  if ((val > -0xa) && (val < 0xa))
2177
    fprintf (file, "%d", val);
2178
  else if (val < 0)
2179
    fprintf (file, "-0x%x", -val);
2180
  else
2181
    fprintf (file, "0x%x", val);
2182
}
2183
 
2184
 
2185
void
2186
print_operand (FILE *file, rtx x, int letter)
2187
{
2188
  if (!x)
2189
    error ("PRINT_OPERAND null pointer");
2190
 
2191
  switch (letter)
2192
    {
2193
    case 'D':
2194
      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2195
        fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2196
      else
2197
        output_operand_lossage ("invalid %%D value");
2198
      break;
2199
 
2200
    case 'v':
2201
      if (GET_CODE (x) == MEM)
2202
        {
2203
          /* For a volatile memory reference, emit a MEMW before the
2204
             load or store.  */
2205
          if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2206
            fprintf (file, "memw\n\t");
2207
        }
2208
      else
2209
        output_operand_lossage ("invalid %%v value");
2210
      break;
2211
 
2212
    case 'N':
2213
      if (GET_CODE (x) == MEM
2214
          && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2215
        {
2216
          x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
2217
          output_address (XEXP (x, 0));
2218
        }
2219
      else
2220
        output_operand_lossage ("invalid %%N value");
2221
      break;
2222
 
2223
    case 'K':
2224
      if (GET_CODE (x) == CONST_INT)
2225
        {
2226
          int num_bits = 0;
2227
          unsigned val = INTVAL (x);
2228
          while (val & 1)
2229
            {
2230
              num_bits += 1;
2231
              val = val >> 1;
2232
            }
2233
          if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2234
            fatal_insn ("invalid mask", x);
2235
 
2236
          fprintf (file, "%d", num_bits);
2237
        }
2238
      else
2239
        output_operand_lossage ("invalid %%K value");
2240
      break;
2241
 
2242
    case 'L':
2243
      if (GET_CODE (x) == CONST_INT)
2244
        fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
2245
      else
2246
        output_operand_lossage ("invalid %%L value");
2247
      break;
2248
 
2249
    case 'R':
2250
      if (GET_CODE (x) == CONST_INT)
2251
        fprintf (file, "%ld", INTVAL (x) & 0x1f);
2252
      else
2253
        output_operand_lossage ("invalid %%R value");
2254
      break;
2255
 
2256
    case 'x':
2257
      if (GET_CODE (x) == CONST_INT)
2258
        printx (file, INTVAL (x));
2259
      else
2260
        output_operand_lossage ("invalid %%x value");
2261
      break;
2262
 
2263
    case 'd':
2264
      if (GET_CODE (x) == CONST_INT)
2265
        fprintf (file, "%ld", INTVAL (x));
2266
      else
2267
        output_operand_lossage ("invalid %%d value");
2268
      break;
2269
 
2270
    case 't':
2271
    case 'b':
2272
      if (GET_CODE (x) == CONST_INT)
2273
        {
2274
          printx (file, INTVAL (x));
2275
          fputs (letter == 't' ? "@h" : "@l", file);
2276
        }
2277
      else if (GET_CODE (x) == CONST_DOUBLE)
2278
        {
2279
          REAL_VALUE_TYPE r;
2280
          REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2281
          if (GET_MODE (x) == SFmode)
2282
            {
2283
              long l;
2284
              REAL_VALUE_TO_TARGET_SINGLE (r, l);
2285
              fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2286
            }
2287
          else
2288
            output_operand_lossage ("invalid %%t/%%b value");
2289
        }
2290
      else if (GET_CODE (x) == CONST)
2291
        {
2292
          /* X must be a symbolic constant on ELF.  Write an expression
2293
             suitable for 'const16' that sets the high or low 16 bits.  */
2294
          if (GET_CODE (XEXP (x, 0)) != PLUS
2295
              || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2296
                  && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2297
              || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2298
            output_operand_lossage ("invalid %%t/%%b value");
2299
          print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2300
          fputs (letter == 't' ? "@h" : "@l", file);
2301
          /* There must be a non-alphanumeric character between 'h' or 'l'
2302
             and the number.  The '-' is added by print_operand() already.  */
2303
          if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2304
            fputs ("+", file);
2305
          print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2306
        }
2307
      else
2308
        {
2309
          output_addr_const (file, x);
2310
          fputs (letter == 't' ? "@h" : "@l", file);
2311
        }
2312
      break;
2313
 
2314
    default:
2315
      if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2316
        fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2317
      else if (GET_CODE (x) == MEM)
2318
        output_address (XEXP (x, 0));
2319
      else if (GET_CODE (x) == CONST_INT)
2320
        fprintf (file, "%ld", INTVAL (x));
2321
      else
2322
        output_addr_const (file, x);
2323
    }
2324
}
2325
 
2326
 
2327
/* A C compound statement to output to stdio stream STREAM the
2328
   assembler syntax for an instruction operand that is a memory
2329
   reference whose address is ADDR.  ADDR is an RTL expression.  */
2330
 
2331
void
2332
print_operand_address (FILE *file, rtx addr)
2333
{
2334
  if (!addr)
2335
    error ("PRINT_OPERAND_ADDRESS, null pointer");
2336
 
2337
  switch (GET_CODE (addr))
2338
    {
2339
    default:
2340
      fatal_insn ("invalid address", addr);
2341
      break;
2342
 
2343
    case REG:
2344
      fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2345
      break;
2346
 
2347
    case PLUS:
2348
      {
2349
        rtx reg = (rtx)0;
2350
        rtx offset = (rtx)0;
2351
        rtx arg0 = XEXP (addr, 0);
2352
        rtx arg1 = XEXP (addr, 1);
2353
 
2354
        if (GET_CODE (arg0) == REG)
2355
          {
2356
            reg = arg0;
2357
            offset = arg1;
2358
          }
2359
        else if (GET_CODE (arg1) == REG)
2360
          {
2361
            reg = arg1;
2362
            offset = arg0;
2363
          }
2364
        else
2365
          fatal_insn ("no register in address", addr);
2366
 
2367
        if (CONSTANT_P (offset))
2368
          {
2369
            fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2370
            output_addr_const (file, offset);
2371
          }
2372
        else
2373
          fatal_insn ("address offset not a constant", addr);
2374
      }
2375
      break;
2376
 
2377
    case LABEL_REF:
2378
    case SYMBOL_REF:
2379
    case CONST_INT:
2380
    case CONST:
2381
      output_addr_const (file, addr);
2382
      break;
2383
    }
2384
}
2385
 
2386
 
2387
bool
2388
xtensa_output_addr_const_extra (FILE *fp, rtx x)
2389
{
2390
  if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2391
    {
2392
      switch (XINT (x, 1))
2393
        {
2394
        case UNSPEC_TPOFF:
2395
          output_addr_const (fp, XVECEXP (x, 0, 0));
2396
          fputs ("@TPOFF", fp);
2397
          return true;
2398
        case UNSPEC_DTPOFF:
2399
          output_addr_const (fp, XVECEXP (x, 0, 0));
2400
          fputs ("@DTPOFF", fp);
2401
          return true;
2402
        case UNSPEC_PLT:
2403
          if (flag_pic)
2404
            {
2405
              output_addr_const (fp, XVECEXP (x, 0, 0));
2406
              fputs ("@PLT", fp);
2407
              return true;
2408
            }
2409
          break;
2410
        default:
2411
          break;
2412
        }
2413
    }
2414
  return false;
2415
}
2416
 
2417
 
2418
void
2419
xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
2420
{
2421
  long value_long[2];
2422
  REAL_VALUE_TYPE r;
2423
  int size;
2424
  rtx first, second;
2425
 
2426
  fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2427
 
2428
  switch (GET_MODE_CLASS (mode))
2429
    {
2430
    case MODE_FLOAT:
2431
      gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2432
 
2433
      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2434
      switch (mode)
2435
        {
2436
        case SFmode:
2437
          REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
2438
          if (HOST_BITS_PER_LONG > 32)
2439
            value_long[0] &= 0xffffffff;
2440
          fprintf (file, "0x%08lx\n", value_long[0]);
2441
          break;
2442
 
2443
        case DFmode:
2444
          REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
2445
          if (HOST_BITS_PER_LONG > 32)
2446
            {
2447
              value_long[0] &= 0xffffffff;
2448
              value_long[1] &= 0xffffffff;
2449
            }
2450
          fprintf (file, "0x%08lx, 0x%08lx\n",
2451
                   value_long[0], value_long[1]);
2452
          break;
2453
 
2454
        default:
2455
          gcc_unreachable ();
2456
        }
2457
 
2458
      break;
2459
 
2460
    case MODE_INT:
2461
    case MODE_PARTIAL_INT:
2462
      size = GET_MODE_SIZE (mode);
2463
      switch (size)
2464
        {
2465
        case 4:
2466
          output_addr_const (file, x);
2467
          fputs ("\n", file);
2468
          break;
2469
 
2470
        case 8:
2471
          split_double (x, &first, &second);
2472
          output_addr_const (file, first);
2473
          fputs (", ", file);
2474
          output_addr_const (file, second);
2475
          fputs ("\n", file);
2476
          break;
2477
 
2478
        default:
2479
          gcc_unreachable ();
2480
        }
2481
      break;
2482
 
2483
    default:
2484
      gcc_unreachable ();
2485
    }
2486
}
2487
 
2488
 
2489
/* Return the bytes needed to compute the frame pointer from the current
2490
   stack pointer.  */
2491
 
2492
#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2493
#define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2494
 
2495
long
2496
compute_frame_size (int size)
2497
{
2498
  /* Add space for the incoming static chain value.  */
2499
  if (cfun->static_chain_decl != NULL)
2500
    size += (1 * UNITS_PER_WORD);
2501
 
2502
  xtensa_current_frame_size =
2503
    XTENSA_STACK_ALIGN (size
2504
                        + crtl->outgoing_args_size
2505
                        + (WINDOW_SIZE * UNITS_PER_WORD));
2506
  return xtensa_current_frame_size;
2507
}
2508
 
2509
 
2510
bool
2511
xtensa_frame_pointer_required (void)
2512
{
2513
  /* The code to expand builtin_frame_addr and builtin_return_addr
2514
     currently uses the hard_frame_pointer instead of frame_pointer.
2515
     This seems wrong but maybe it's necessary for other architectures.
2516
     This function is derived from the i386 code.  */
2517
 
2518
  if (cfun->machine->accesses_prev_frame)
2519
    return true;
2520
 
2521
  return false;
2522
}
2523
 
2524
 
2525
/* minimum frame = reg save area (4 words) plus static chain (1 word)
2526
   and the total number of words must be a multiple of 128 bits.  */
2527
#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2528
 
2529
void
2530
xtensa_expand_prologue (void)
2531
{
2532
  HOST_WIDE_INT total_size;
2533
  rtx size_rtx;
2534
  rtx insn, note_rtx;
2535
 
2536
  total_size = compute_frame_size (get_frame_size ());
2537
  size_rtx = GEN_INT (total_size);
2538
 
2539
  if (total_size < (1 << (12+3)))
2540
    insn = emit_insn (gen_entry (size_rtx));
2541
  else
2542
    {
2543
      /* Use a8 as a temporary since a0-a7 may be live.  */
2544
      rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2545
      emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2546
      emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2547
      emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2548
      insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2549
    }
2550
 
2551
  if (frame_pointer_needed)
2552
    {
2553
      if (cfun->machine->set_frame_ptr_insn)
2554
        {
2555
          rtx first;
2556
 
2557
          push_topmost_sequence ();
2558
          first = get_insns ();
2559
          pop_topmost_sequence ();
2560
 
2561
          /* For all instructions prior to set_frame_ptr_insn, replace
2562
             hard_frame_pointer references with stack_pointer.  */
2563
          for (insn = first;
2564
               insn != cfun->machine->set_frame_ptr_insn;
2565
               insn = NEXT_INSN (insn))
2566
            {
2567
              if (INSN_P (insn))
2568
                {
2569
                  PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2570
                                                hard_frame_pointer_rtx,
2571
                                                stack_pointer_rtx);
2572
                  df_insn_rescan (insn);
2573
                }
2574
            }
2575
        }
2576
      else
2577
        insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2578
                                     stack_pointer_rtx));
2579
    }
2580
 
2581
  /* Create a note to describe the CFA.  Because this is only used to set
2582
     DW_AT_frame_base for debug info, don't bother tracking changes through
2583
     each instruction in the prologue.  It just takes up space.  */
2584
  note_rtx = gen_rtx_SET (VOIDmode, (frame_pointer_needed
2585
                                     ? hard_frame_pointer_rtx
2586
                                     : stack_pointer_rtx),
2587
                          plus_constant (stack_pointer_rtx, -total_size));
2588
  RTX_FRAME_RELATED_P (insn) = 1;
2589
  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2590
                                        note_rtx, REG_NOTES (insn));
2591
}
2592
 
2593
 
2594
/* Clear variables at function end.  */
2595
 
2596
void
2597
xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
2598
                          HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2599
{
2600
  xtensa_current_frame_size = 0;
2601
}
2602
 
2603
 
2604
rtx
2605
xtensa_return_addr (int count, rtx frame)
2606
{
2607
  rtx result, retaddr, curaddr, label;
2608
 
2609
  if (count == -1)
2610
    retaddr = gen_rtx_REG (Pmode, A0_REG);
2611
  else
2612
    {
2613
      rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
2614
      addr = memory_address (Pmode, addr);
2615
      retaddr = gen_reg_rtx (Pmode);
2616
      emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
2617
    }
2618
 
2619
  /* The 2 most-significant bits of the return address on Xtensa hold
2620
     the register window size.  To get the real return address, these
2621
     bits must be replaced with the high bits from some address in the
2622
     code.  */
2623
 
2624
  /* Get the 2 high bits of a local label in the code.  */
2625
  curaddr = gen_reg_rtx (Pmode);
2626
  label = gen_label_rtx ();
2627
  emit_label (label);
2628
  LABEL_PRESERVE_P (label) = 1;
2629
  emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
2630
  emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
2631
  emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
2632
 
2633
  /* Clear the 2 high bits of the return address.  */
2634
  result = gen_reg_rtx (Pmode);
2635
  emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
2636
  emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
2637
 
2638
  /* Combine them to get the result.  */
2639
  emit_insn (gen_iorsi3 (result, result, curaddr));
2640
  return result;
2641
}
2642
 
2643
 
2644
/* Create the va_list data type.
2645
 
2646
   This structure is set up by __builtin_saveregs.  The __va_reg field
2647
   points to a stack-allocated region holding the contents of the
2648
   incoming argument registers.  The __va_ndx field is an index
2649
   initialized to the position of the first unnamed (variable)
2650
   argument.  This same index is also used to address the arguments
2651
   passed in memory.  Thus, the __va_stk field is initialized to point
2652
   to the position of the first argument in memory offset to account
2653
   for the arguments passed in registers and to account for the size
2654
   of the argument registers not being 16-byte aligned.  E.G., there
2655
   are 6 argument registers of 4 bytes each, but we want the __va_ndx
2656
   for the first stack argument to have the maximal alignment of 16
2657
   bytes, so we offset the __va_stk address by 32 bytes so that
2658
   __va_stk[32] references the first argument on the stack.  */
2659
 
2660
static tree
2661
xtensa_build_builtin_va_list (void)
2662
{
2663
  tree f_stk, f_reg, f_ndx, record, type_decl;
2664
 
2665
  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2666
  type_decl = build_decl (BUILTINS_LOCATION,
2667
                          TYPE_DECL, get_identifier ("__va_list_tag"), record);
2668
 
2669
  f_stk = build_decl (BUILTINS_LOCATION,
2670
                      FIELD_DECL, get_identifier ("__va_stk"),
2671
                      ptr_type_node);
2672
  f_reg = build_decl (BUILTINS_LOCATION,
2673
                      FIELD_DECL, get_identifier ("__va_reg"),
2674
                      ptr_type_node);
2675
  f_ndx = build_decl (BUILTINS_LOCATION,
2676
                      FIELD_DECL, get_identifier ("__va_ndx"),
2677
                      integer_type_node);
2678
 
2679
  DECL_FIELD_CONTEXT (f_stk) = record;
2680
  DECL_FIELD_CONTEXT (f_reg) = record;
2681
  DECL_FIELD_CONTEXT (f_ndx) = record;
2682
 
2683
  TREE_CHAIN (record) = type_decl;
2684
  TYPE_NAME (record) = type_decl;
2685
  TYPE_FIELDS (record) = f_stk;
2686
  TREE_CHAIN (f_stk) = f_reg;
2687
  TREE_CHAIN (f_reg) = f_ndx;
2688
 
2689
  layout_type (record);
2690
  return record;
2691
}
2692
 
2693
 
2694
/* Save the incoming argument registers on the stack.  Returns the
2695
   address of the saved registers.  */
2696
 
2697
static rtx
2698
xtensa_builtin_saveregs (void)
2699
{
2700
  rtx gp_regs;
2701
  int arg_words = crtl->args.info.arg_words;
2702
  int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
2703
 
2704
  if (gp_left <= 0)
2705
    return const0_rtx;
2706
 
2707
  /* Allocate the general-purpose register space.  */
2708
  gp_regs = assign_stack_local
2709
    (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
2710
  set_mem_alias_set (gp_regs, get_varargs_alias_set ());
2711
 
2712
  /* Now store the incoming registers.  */
2713
  cfun->machine->need_a7_copy = true;
2714
  cfun->machine->vararg_a7 = true;
2715
  move_block_from_reg (GP_ARG_FIRST + arg_words,
2716
                       adjust_address (gp_regs, BLKmode,
2717
                                       arg_words * UNITS_PER_WORD),
2718
                       gp_left);
2719
  gcc_assert (cfun->machine->vararg_a7_copy != 0);
2720
  emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
2721
 
2722
  return XEXP (gp_regs, 0);
2723
}
2724
 
2725
 
2726
/* Implement `va_start' for varargs and stdarg.  We look at the
2727
   current function to fill in an initial va_list.  */
2728
 
2729
static void
2730
xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
2731
{
2732
  tree f_stk, stk;
2733
  tree f_reg, reg;
2734
  tree f_ndx, ndx;
2735
  tree t, u;
2736
  int arg_words;
2737
 
2738
  arg_words = crtl->args.info.arg_words;
2739
 
2740
  f_stk = TYPE_FIELDS (va_list_type_node);
2741
  f_reg = TREE_CHAIN (f_stk);
2742
  f_ndx = TREE_CHAIN (f_reg);
2743
 
2744
  stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2745
  reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2746
                f_reg, NULL_TREE);
2747
  ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2748
                f_ndx, NULL_TREE);
2749
 
2750
  /* Call __builtin_saveregs; save the result in __va_reg */
2751
  u = make_tree (sizetype, expand_builtin_saveregs ());
2752
  u = fold_convert (ptr_type_node, u);
2753
  t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
2754
  TREE_SIDE_EFFECTS (t) = 1;
2755
  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2756
 
2757
  /* Set the __va_stk member to ($arg_ptr - 32).  */
2758
  u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
2759
  u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, size_int (-32));
2760
  t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
2761
  TREE_SIDE_EFFECTS (t) = 1;
2762
  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2763
 
2764
  /* Set the __va_ndx member.  If the first variable argument is on
2765
     the stack, adjust __va_ndx by 2 words to account for the extra
2766
     alignment offset for __va_stk.  */
2767
  if (arg_words >= MAX_ARGS_IN_REGISTERS)
2768
    arg_words += 2;
2769
  t = build2 (MODIFY_EXPR, integer_type_node, ndx,
2770
              build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
2771
  TREE_SIDE_EFFECTS (t) = 1;
2772
  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2773
}
2774
 
2775
 
2776
/* Implement `va_arg'.  */
2777
 
2778
static tree
2779
xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
2780
                             gimple_seq *post_p ATTRIBUTE_UNUSED)
2781
{
2782
  tree f_stk, stk;
2783
  tree f_reg, reg;
2784
  tree f_ndx, ndx;
2785
  tree type_size, array, orig_ndx, addr, size, va_size, t;
2786
  tree lab_false, lab_over, lab_false2;
2787
  bool indirect;
2788
 
2789
  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2790
  if (indirect)
2791
    type = build_pointer_type (type);
2792
 
2793
  /* Handle complex values as separate real and imaginary parts.  */
2794
  if (TREE_CODE (type) == COMPLEX_TYPE)
2795
    {
2796
      tree real_part, imag_part;
2797
 
2798
      real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2799
                                               pre_p, NULL);
2800
      real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
2801
 
2802
      imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
2803
                                               TREE_TYPE (type),
2804
                                               pre_p, NULL);
2805
      imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
2806
 
2807
      return build2 (COMPLEX_EXPR, type, real_part, imag_part);
2808
    }
2809
 
2810
  f_stk = TYPE_FIELDS (va_list_type_node);
2811
  f_reg = TREE_CHAIN (f_stk);
2812
  f_ndx = TREE_CHAIN (f_reg);
2813
 
2814
  stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
2815
                f_stk, NULL_TREE);
2816
  reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
2817
                f_reg, NULL_TREE);
2818
  ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
2819
                f_ndx, NULL_TREE);
2820
 
2821
  type_size = size_in_bytes (type);
2822
  va_size = round_up (type_size, UNITS_PER_WORD);
2823
  gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
2824
 
2825
 
2826
  /* First align __va_ndx if necessary for this arg:
2827
 
2828
     orig_ndx = (AP).__va_ndx;
2829
     if (__alignof__ (TYPE) > 4 )
2830
       orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2831
                        & -__alignof__ (TYPE)); */
2832
 
2833
  orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2834
 
2835
  if (TYPE_ALIGN (type) > BITS_PER_WORD)
2836
    {
2837
      int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
2838
 
2839
      t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
2840
                  build_int_cst (integer_type_node, align - 1));
2841
      t = build2 (BIT_AND_EXPR, integer_type_node, t,
2842
                  build_int_cst (integer_type_node, -align));
2843
      gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
2844
    }
2845
 
2846
 
2847
  /* Increment __va_ndx to point past the argument:
2848
 
2849
     (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2850
 
2851
  t = fold_convert (integer_type_node, va_size);
2852
  t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
2853
  gimplify_assign (unshare_expr (ndx), t, pre_p);
2854
 
2855
 
2856
  /* Check if the argument is in registers:
2857
 
2858
     if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2859
         && !must_pass_in_stack (type))
2860
        __array = (AP).__va_reg; */
2861
 
2862
  array = create_tmp_var (ptr_type_node, NULL);
2863
 
2864
  lab_over = NULL;
2865
  if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2866
    {
2867
      lab_false = create_artificial_label (UNKNOWN_LOCATION);
2868
      lab_over = create_artificial_label (UNKNOWN_LOCATION);
2869
 
2870
      t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
2871
                  build_int_cst (integer_type_node,
2872
                                 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2873
      t = build3 (COND_EXPR, void_type_node, t,
2874
                  build1 (GOTO_EXPR, void_type_node, lab_false),
2875
                  NULL_TREE);
2876
      gimplify_and_add (t, pre_p);
2877
 
2878
      gimplify_assign (unshare_expr (array), reg, pre_p);
2879
 
2880
      t = build1 (GOTO_EXPR, void_type_node, lab_over);
2881
      gimplify_and_add (t, pre_p);
2882
 
2883
      t = build1 (LABEL_EXPR, void_type_node, lab_false);
2884
      gimplify_and_add (t, pre_p);
2885
    }
2886
 
2887
 
2888
  /* ...otherwise, the argument is on the stack (never split between
2889
     registers and the stack -- change __va_ndx if necessary):
2890
 
2891
     else
2892
       {
2893
         if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2894
             (AP).__va_ndx = 32 + __va_size (TYPE);
2895
         __array = (AP).__va_stk;
2896
       } */
2897
 
2898
  lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
2899
 
2900
  t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
2901
              build_int_cst (integer_type_node,
2902
                             MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2903
  t = build3 (COND_EXPR, void_type_node, t,
2904
              build1 (GOTO_EXPR, void_type_node, lab_false2),
2905
              NULL_TREE);
2906
  gimplify_and_add (t, pre_p);
2907
 
2908
  t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
2909
  t = fold_convert (integer_type_node, t);
2910
  gimplify_assign (unshare_expr (ndx), t, pre_p);
2911
 
2912
  t = build1 (LABEL_EXPR, void_type_node, lab_false2);
2913
  gimplify_and_add (t, pre_p);
2914
 
2915
  gimplify_assign (array, stk, pre_p);
2916
 
2917
  if (lab_over)
2918
    {
2919
      t = build1 (LABEL_EXPR, void_type_node, lab_over);
2920
      gimplify_and_add (t, pre_p);
2921
    }
2922
 
2923
 
2924
  /* Given the base array pointer (__array) and index to the subsequent
2925
     argument (__va_ndx), find the address:
2926
 
2927
     __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2928
                                ? sizeof (TYPE)
2929
                                : __va_size (TYPE))
2930
 
2931
     The results are endian-dependent because values smaller than one word
2932
     are aligned differently.  */
2933
 
2934
 
2935
  if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
2936
    {
2937
      t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
2938
                       size_int (PARM_BOUNDARY / BITS_PER_UNIT));
2939
      t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
2940
                       unshare_expr (type_size));
2941
      size = t;
2942
    }
2943
  else
2944
    size = unshare_expr (va_size);
2945
 
2946
  t = fold_convert (sizetype, unshare_expr (ndx));
2947
  t = build2 (MINUS_EXPR, sizetype, t, size);
2948
  addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (array), t);
2949
 
2950
  addr = fold_convert (build_pointer_type (type), addr);
2951
  if (indirect)
2952
    addr = build_va_arg_indirect_ref (addr);
2953
  return build_va_arg_indirect_ref (addr);
2954
}
2955
 
2956
 
2957
/* Builtins.  */
2958
 
2959
enum xtensa_builtin
2960
{
2961
  XTENSA_BUILTIN_UMULSIDI3,
2962
  XTENSA_BUILTIN_THREAD_POINTER,
2963
  XTENSA_BUILTIN_SET_THREAD_POINTER,
2964
  XTENSA_BUILTIN_max
2965
};
2966
 
2967
 
2968
static void
2969
xtensa_init_builtins (void)
2970
{
2971
  tree ftype, decl;
2972
 
2973
  ftype = build_function_type_list (unsigned_intDI_type_node,
2974
                                    unsigned_intSI_type_node,
2975
                                    unsigned_intSI_type_node, NULL_TREE);
2976
 
2977
  decl = add_builtin_function ("__builtin_umulsidi3", ftype,
2978
                               XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
2979
                               "__umulsidi3", NULL_TREE);
2980
  TREE_NOTHROW (decl) = 1;
2981
  TREE_READONLY (decl) = 1;
2982
 
2983
  if (TARGET_THREADPTR)
2984
    {
2985
      ftype = build_function_type (ptr_type_node, void_list_node);
2986
      decl = add_builtin_function ("__builtin_thread_pointer", ftype,
2987
                                   XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
2988
                                   NULL, NULL_TREE);
2989
      TREE_READONLY (decl) = 1;
2990
      TREE_NOTHROW (decl) = 1;
2991
 
2992
      ftype = build_function_type_list (void_type_node, ptr_type_node,
2993
                                        NULL_TREE);
2994
      decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
2995
                                   XTENSA_BUILTIN_SET_THREAD_POINTER,
2996
                                   BUILT_IN_MD, NULL, NULL_TREE);
2997
      TREE_NOTHROW (decl) = 1;
2998
    }
2999
}
3000
 
3001
 
3002
static tree
3003
xtensa_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
3004
{
3005
  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3006
  tree arg0, arg1;
3007
 
3008
  switch (fcode)
3009
    {
3010
    case XTENSA_BUILTIN_UMULSIDI3:
3011
      arg0 = TREE_VALUE (arglist);
3012
      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3013
      if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3014
          || TARGET_MUL32_HIGH)
3015
        return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
3016
                            fold_convert (unsigned_intDI_type_node, arg0),
3017
                            fold_convert (unsigned_intDI_type_node, arg1));
3018
      break;
3019
 
3020
    case XTENSA_BUILTIN_THREAD_POINTER:
3021
    case XTENSA_BUILTIN_SET_THREAD_POINTER:
3022
      break;
3023
 
3024
    default:
3025
      internal_error ("bad builtin code");
3026
      break;
3027
    }
3028
 
3029
  return NULL;
3030
}
3031
 
3032
 
3033
static rtx
3034
xtensa_expand_builtin (tree exp, rtx target,
3035
                       rtx subtarget ATTRIBUTE_UNUSED,
3036
                       enum machine_mode mode ATTRIBUTE_UNUSED,
3037
                       int ignore)
3038
{
3039
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3040
  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3041
  rtx arg;
3042
 
3043
  switch (fcode)
3044
    {
3045
    case XTENSA_BUILTIN_UMULSIDI3:
3046
      /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3047
         __umulsidi3 function when the Xtensa configuration can directly
3048
         implement it.  If not, just call the function.  */
3049
      return expand_call (exp, target, ignore);
3050
 
3051
    case XTENSA_BUILTIN_THREAD_POINTER:
3052
      if (!target || !register_operand (target, Pmode))
3053
        target = gen_reg_rtx (Pmode);
3054
      emit_insn (gen_load_tp (target));
3055
      return target;
3056
 
3057
    case XTENSA_BUILTIN_SET_THREAD_POINTER:
3058
      arg = expand_normal (CALL_EXPR_ARG (exp, 0));
3059
      if (!register_operand (arg, Pmode))
3060
        arg = copy_to_mode_reg (Pmode, arg);
3061
      emit_insn (gen_set_tp (arg));
3062
      return const0_rtx;
3063
 
3064
    default:
3065
      internal_error ("bad builtin code");
3066
    }
3067
  return NULL_RTX;
3068
}
3069
 
3070
 
3071
enum reg_class
3072
xtensa_preferred_reload_class (rtx x, enum reg_class rclass, int isoutput)
3073
{
3074
  if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
3075
    return NO_REGS;
3076
 
3077
  /* Don't use the stack pointer or hard frame pointer for reloads!
3078
     The hard frame pointer would normally be OK except that it may
3079
     briefly hold an incoming argument in the prologue, and reload
3080
     won't know that it is live because the hard frame pointer is
3081
     treated specially.  */
3082
 
3083
  if (rclass == AR_REGS || rclass == GR_REGS)
3084
    return RL_REGS;
3085
 
3086
  return rclass;
3087
}
3088
 
3089
 
3090
enum reg_class
3091
xtensa_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
3092
                         enum machine_mode mode, secondary_reload_info *sri)
3093
{
3094
  int regno;
3095
 
3096
  if (in_p && constantpool_mem_p (x))
3097
    {
3098
      if (rclass == FP_REGS)
3099
        return RL_REGS;
3100
 
3101
      if (mode == QImode)
3102
        sri->icode = CODE_FOR_reloadqi_literal;
3103
      else if (mode == HImode)
3104
        sri->icode = CODE_FOR_reloadhi_literal;
3105
    }
3106
 
3107
  regno = xt_true_regnum (x);
3108
  if (ACC_REG_P (regno))
3109
    return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3110
  if (rclass == ACC_REG)
3111
    return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3112
 
3113
  return NO_REGS;
3114
}
3115
 
3116
 
3117
void
3118
order_regs_for_local_alloc (void)
3119
{
3120
  if (!leaf_function_p ())
3121
    {
3122
      memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
3123
              FIRST_PSEUDO_REGISTER * sizeof (int));
3124
    }
3125
  else
3126
    {
3127
      int i, num_arg_regs;
3128
      int nxt = 0;
3129
 
3130
      /* Use the AR registers in increasing order (skipping a0 and a1)
3131
         but save the incoming argument registers for a last resort.  */
3132
      num_arg_regs = crtl->args.info.arg_words;
3133
      if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3134
        num_arg_regs = MAX_ARGS_IN_REGISTERS;
3135
      for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3136
        reg_alloc_order[nxt++] = i + num_arg_regs;
3137
      for (i = 0; i < num_arg_regs; i++)
3138
        reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3139
 
3140
      /* List the coprocessor registers in order.  */
3141
      for (i = 0; i < BR_REG_NUM; i++)
3142
        reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3143
 
3144
      /* List the FP registers in order for now.  */
3145
      for (i = 0; i < 16; i++)
3146
        reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3147
 
3148
      /* GCC requires that we list *all* the registers....  */
3149
      reg_alloc_order[nxt++] = 0;        /* a0 = return address */
3150
      reg_alloc_order[nxt++] = 1;       /* a1 = stack pointer */
3151
      reg_alloc_order[nxt++] = 16;      /* pseudo frame pointer */
3152
      reg_alloc_order[nxt++] = 17;      /* pseudo arg pointer */
3153
 
3154
      reg_alloc_order[nxt++] = ACC_REG_FIRST;   /* MAC16 accumulator */
3155
    }
3156
}
3157
 
3158
 
3159
/* Some Xtensa targets support multiple bss sections.  If the section
3160
   name ends with ".bss", add SECTION_BSS to the flags.  */
3161
 
3162
static unsigned int
3163
xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3164
{
3165
  unsigned int flags = default_section_type_flags (decl, name, reloc);
3166
  const char *suffix;
3167
 
3168
  suffix = strrchr (name, '.');
3169
  if (suffix && strcmp (suffix, ".bss") == 0)
3170
    {
3171
      if (!decl || (TREE_CODE (decl) == VAR_DECL
3172
                    && DECL_INITIAL (decl) == NULL_TREE))
3173
        flags |= SECTION_BSS;  /* @nobits */
3174
      else
3175
        warning (0, "only uninitialized variables can be placed in a "
3176
                 ".bss section");
3177
    }
3178
 
3179
  return flags;
3180
}
3181
 
3182
 
3183
/* The literal pool stays with the function.  */
3184
 
3185
static section *
3186
xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
3187
                           rtx x ATTRIBUTE_UNUSED,
3188
                           unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3189
{
3190
  return function_section (current_function_decl);
3191
}
3192
 
3193
 
3194
/* Compute a (partial) cost for rtx X.  Return true if the complete
3195
   cost has been computed, and false if subexpressions should be
3196
   scanned.  In either case, *TOTAL contains the cost result.  */
3197
 
3198
static bool
3199
xtensa_rtx_costs (rtx x, int code, int outer_code, int *total,
3200
                  bool speed ATTRIBUTE_UNUSED)
3201
{
3202
  switch (code)
3203
    {
3204
    case CONST_INT:
3205
      switch (outer_code)
3206
        {
3207
        case SET:
3208
          if (xtensa_simm12b (INTVAL (x)))
3209
            {
3210
              *total = 4;
3211
              return true;
3212
            }
3213
          break;
3214
        case PLUS:
3215
          if (xtensa_simm8 (INTVAL (x))
3216
              || xtensa_simm8x256 (INTVAL (x)))
3217
            {
3218
              *total = 0;
3219
              return true;
3220
            }
3221
          break;
3222
        case AND:
3223
          if (xtensa_mask_immediate (INTVAL (x)))
3224
            {
3225
              *total = 0;
3226
              return true;
3227
            }
3228
          break;
3229
        case COMPARE:
3230
          if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3231
            {
3232
              *total = 0;
3233
              return true;
3234
            }
3235
          break;
3236
        case ASHIFT:
3237
        case ASHIFTRT:
3238
        case LSHIFTRT:
3239
        case ROTATE:
3240
        case ROTATERT:
3241
          /* No way to tell if X is the 2nd operand so be conservative.  */
3242
        default: break;
3243
        }
3244
      if (xtensa_simm12b (INTVAL (x)))
3245
        *total = 5;
3246
      else if (TARGET_CONST16)
3247
        *total = COSTS_N_INSNS (2);
3248
      else
3249
        *total = 6;
3250
      return true;
3251
 
3252
    case CONST:
3253
    case LABEL_REF:
3254
    case SYMBOL_REF:
3255
      if (TARGET_CONST16)
3256
        *total = COSTS_N_INSNS (2);
3257
      else
3258
        *total = 5;
3259
      return true;
3260
 
3261
    case CONST_DOUBLE:
3262
      if (TARGET_CONST16)
3263
        *total = COSTS_N_INSNS (4);
3264
      else
3265
        *total = 7;
3266
      return true;
3267
 
3268
    case MEM:
3269
      {
3270
        int num_words =
3271
          (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ?  2 : 1;
3272
 
3273
        if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
3274
          *total = COSTS_N_INSNS (num_words);
3275
        else
3276
          *total = COSTS_N_INSNS (2*num_words);
3277
        return true;
3278
      }
3279
 
3280
    case FFS:
3281
    case CTZ:
3282
      *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3283
      return true;
3284
 
3285
    case CLZ:
3286
      *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3287
      return true;
3288
 
3289
    case NOT:
3290
      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
3291
      return true;
3292
 
3293
    case AND:
3294
    case IOR:
3295
    case XOR:
3296
      if (GET_MODE (x) == DImode)
3297
        *total = COSTS_N_INSNS (2);
3298
      else
3299
        *total = COSTS_N_INSNS (1);
3300
      return true;
3301
 
3302
    case ASHIFT:
3303
    case ASHIFTRT:
3304
    case LSHIFTRT:
3305
      if (GET_MODE (x) == DImode)
3306
        *total = COSTS_N_INSNS (50);
3307
      else
3308
        *total = COSTS_N_INSNS (1);
3309
      return true;
3310
 
3311
    case ABS:
3312
      {
3313
        enum machine_mode xmode = GET_MODE (x);
3314
        if (xmode == SFmode)
3315
          *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3316
        else if (xmode == DFmode)
3317
          *total = COSTS_N_INSNS (50);
3318
        else
3319
          *total = COSTS_N_INSNS (4);
3320
        return true;
3321
      }
3322
 
3323
    case PLUS:
3324
    case MINUS:
3325
      {
3326
        enum machine_mode xmode = GET_MODE (x);
3327
        if (xmode == SFmode)
3328
          *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3329
        else if (xmode == DFmode || xmode == DImode)
3330
          *total = COSTS_N_INSNS (50);
3331
        else
3332
          *total = COSTS_N_INSNS (1);
3333
        return true;
3334
      }
3335
 
3336
    case NEG:
3337
      *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
3338
      return true;
3339
 
3340
    case MULT:
3341
      {
3342
        enum machine_mode xmode = GET_MODE (x);
3343
        if (xmode == SFmode)
3344
          *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3345
        else if (xmode == DFmode)
3346
          *total = COSTS_N_INSNS (50);
3347
        else if (xmode == DImode)
3348
          *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3349
        else if (TARGET_MUL32)
3350
          *total = COSTS_N_INSNS (4);
3351
        else if (TARGET_MAC16)
3352
          *total = COSTS_N_INSNS (16);
3353
        else if (TARGET_MUL16)
3354
          *total = COSTS_N_INSNS (12);
3355
        else
3356
          *total = COSTS_N_INSNS (50);
3357
        return true;
3358
      }
3359
 
3360
    case DIV:
3361
    case MOD:
3362
      {
3363
        enum machine_mode xmode = GET_MODE (x);
3364
        if (xmode == SFmode)
3365
          {
3366
            *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3367
            return true;
3368
          }
3369
        else if (xmode == DFmode)
3370
          {
3371
            *total = COSTS_N_INSNS (50);
3372
            return true;
3373
          }
3374
      }
3375
      /* Fall through.  */
3376
 
3377
    case UDIV:
3378
    case UMOD:
3379
      {
3380
        enum machine_mode xmode = GET_MODE (x);
3381
        if (xmode == DImode)
3382
          *total = COSTS_N_INSNS (50);
3383
        else if (TARGET_DIV32)
3384
          *total = COSTS_N_INSNS (32);
3385
        else
3386
          *total = COSTS_N_INSNS (50);
3387
        return true;
3388
      }
3389
 
3390
    case SQRT:
3391
      if (GET_MODE (x) == SFmode)
3392
        *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3393
      else
3394
        *total = COSTS_N_INSNS (50);
3395
      return true;
3396
 
3397
    case SMIN:
3398
    case UMIN:
3399
    case SMAX:
3400
    case UMAX:
3401
      *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3402
      return true;
3403
 
3404
    case SIGN_EXTRACT:
3405
    case SIGN_EXTEND:
3406
      *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3407
      return true;
3408
 
3409
    case ZERO_EXTRACT:
3410
    case ZERO_EXTEND:
3411
      *total = COSTS_N_INSNS (1);
3412
      return true;
3413
 
3414
    default:
3415
      return false;
3416
    }
3417
}
3418
 
3419
/* Worker function for TARGET_RETURN_IN_MEMORY.  */
3420
 
3421
static bool
3422
xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3423
{
3424
  return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3425
          > 4 * UNITS_PER_WORD);
3426
}
3427
 
3428
/* Worker function for TARGET_FUNCTION_VALUE.  */
3429
 
3430
rtx
3431
xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3432
                      bool outgoing)
3433
{
3434
  return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3435
                      && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3436
                     ? SImode : TYPE_MODE (valtype),
3437
                     outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3438
}
3439
 
3440
/* The static chain is passed in memory.  Provide rtx giving 'mem'
3441
   expressions that denote where they are stored.  */
3442
 
3443
static rtx
3444
xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
3445
{
3446
  rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3447
  return gen_frame_mem (Pmode, plus_constant (base, -5 * UNITS_PER_WORD));
3448
}
3449
 
3450
 
3451
/* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3452
   instruction with a minimal stack frame in order to get some free
3453
   registers.  Once the actual call target is known, the proper stack frame
3454
   size is extracted from the ENTRY instruction at the target and the
3455
   current frame is adjusted to match.  The trampoline then transfers
3456
   control to the instruction following the ENTRY at the target.  Note:
3457
   this assumes that the target begins with an ENTRY instruction.  */
3458
 
3459
static void
3460
xtensa_asm_trampoline_template (FILE *stream)
3461
{
3462
  bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3463
 
3464
  fprintf (stream, "\t.begin no-transform\n");
3465
  fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3466
 
3467
  if (use_call0)
3468
    {
3469
      /* Save the return address.  */
3470
      fprintf (stream, "\tmov\ta10, a0\n");
3471
 
3472
      /* Use a CALL0 instruction to skip past the constants and in the
3473
         process get the PC into A0.  This allows PC-relative access to
3474
         the constants without relying on L32R.  */
3475
      fprintf (stream, "\tcall0\t.Lskipconsts\n");
3476
    }
3477
  else
3478
    fprintf (stream, "\tj\t.Lskipconsts\n");
3479
 
3480
  fprintf (stream, "\t.align\t4\n");
3481
  fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3482
  fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3483
  fprintf (stream, ".Lskipconsts:\n");
3484
 
3485
  /* Load the static chain and function address from the trampoline.  */
3486
  if (use_call0)
3487
    {
3488
      fprintf (stream, "\taddi\ta0, a0, 3\n");
3489
      fprintf (stream, "\tl32i\ta9, a0, 0\n");
3490
      fprintf (stream, "\tl32i\ta8, a0, 4\n");
3491
    }
3492
  else
3493
    {
3494
      fprintf (stream, "\tl32r\ta9, .Lchainval\n");
3495
      fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
3496
    }
3497
 
3498
  /* Store the static chain.  */
3499
  fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
3500
 
3501
  /* Set the proper stack pointer value.  */
3502
  fprintf (stream, "\tl32i\ta9, a8, 0\n");
3503
  fprintf (stream, "\textui\ta9, a9, %d, 12\n",
3504
           TARGET_BIG_ENDIAN ? 8 : 12);
3505
  fprintf (stream, "\tslli\ta9, a9, 3\n");
3506
  fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
3507
  fprintf (stream, "\tsub\ta9, sp, a9\n");
3508
  fprintf (stream, "\tmovsp\tsp, a9\n");
3509
 
3510
  if (use_call0)
3511
    /* Restore the return address.  */
3512
    fprintf (stream, "\tmov\ta0, a10\n");
3513
 
3514
  /* Jump to the instruction following the ENTRY.  */
3515
  fprintf (stream, "\taddi\ta8, a8, 3\n");
3516
  fprintf (stream, "\tjx\ta8\n");
3517
 
3518
  /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT.  */
3519
  if (use_call0)
3520
    fprintf (stream, "\t.byte\t0\n");
3521
  else
3522
    fprintf (stream, "\tnop\n");
3523
 
3524
  fprintf (stream, "\t.end no-transform\n");
3525
}
3526
 
3527
static void
3528
xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
3529
{
3530
  rtx func = XEXP (DECL_RTL (fndecl), 0);
3531
  bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3532
  int chain_off = use_call0 ? 12 : 8;
3533
  int func_off = use_call0 ? 16 : 12;
3534
 
3535
  emit_block_move (m_tramp, assemble_trampoline_template (),
3536
                   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3537
 
3538
  emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
3539
  emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
3540
  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
3541
                     0, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
3542
}
3543
 
3544
 
3545
#include "gt-xtensa.h"

powered by: WebSVN 2.1.0

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