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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [xtensa/] [xtensa.c] - Blame information for rev 709

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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