]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/xtensa/xtensa.c
re PR target/13506 (tcpsm.c:263: internal compiler error: Segmentation fault)
[thirdparty/gcc.git] / gcc / config / xtensa / xtensa.c
CommitLineData
03984308 1/* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
4c45af42 2 Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
03984308
BW
3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
03984308
BW
26#include "rtl.h"
27#include "regs.h"
03984308
BW
28#include "hard-reg-set.h"
29#include "basic-block.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
33#include "insn-flags.h"
34#include "insn-attr.h"
35#include "insn-codes.h"
36#include "recog.h"
37#include "output.h"
38#include "tree.h"
39#include "expr.h"
40#include "flags.h"
41#include "reload.h"
42#include "tm_p.h"
43#include "function.h"
44#include "toplev.h"
45#include "optabs.h"
46#include "libfuncs.h"
07232638 47#include "ggc.h"
03984308
BW
48#include "target.h"
49#include "target-def.h"
540eaea8 50#include "langhooks.h"
85d53c1d
RH
51#include "tree-gimple.h"
52
03984308
BW
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
638db43e 56 of EQ, NE, etc. */
03984308 57
ffbc8796
BW
58enum 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};
03984308
BW
72
73/* Cached operands, and operator to compare for use in set/branch on
74 condition codes. */
75rtx branch_cmp[2];
76
77/* what type of branch to use */
78enum cmp_type branch_type;
79
80/* Array giving truth value on whether or not a given hard register
81 can support a given mode. */
82char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
83
84/* Current frame size calculated by compute_frame_size. */
85unsigned xtensa_current_frame_size;
86
87/* Tables of ld/st opcode names for block moves */
88const char *xtensa_ld_opcodes[(int) MAX_MACHINE_MODE];
89const char *xtensa_st_opcodes[(int) MAX_MACHINE_MODE];
90#define LARGEST_MOVE_RATIO 15
91
92/* Define the structure for the machine field in struct function. */
e2500fed 93struct machine_function GTY(())
03984308
BW
94{
95 int accesses_prev_frame;
997b8b4d
BW
96 bool need_a7_copy;
97 bool vararg_a7;
98 rtx set_frame_ptr_insn;
03984308
BW
99};
100
101/* Vector, indexed by hard register number, which contains 1 for a
102 register that is allowable in a candidate for leaf function
638db43e 103 treatment. */
03984308
BW
104
105const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
106{
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
108 1, 1, 1,
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110 1
111};
112
113/* Map hard register number to register class */
114const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
115{
89f6025d
BW
116 RL_REGS, SP_REG, RL_REGS, RL_REGS,
117 RL_REGS, RL_REGS, RL_REGS, GR_REGS,
118 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
119 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
03984308
BW
120 AR_REGS, AR_REGS, BR_REGS,
121 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
122 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
123 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
124 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
125 ACC_REG,
126};
127
128/* Map register constraint character to register class. */
129enum reg_class xtensa_char_to_class[256] =
130{
131 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
132 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
133 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
134 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
135 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
136 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
137 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
138 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
139 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
140 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
141 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
142 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
143 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
144 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
145 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
146 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
147 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
148 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
149 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
150 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
151 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
152 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
153 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
154 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
155 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
156 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
157 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
158 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
159 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
160 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
161 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
162 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
163 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
164 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
165 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
166 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
167 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
168 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
169 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
170 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
171 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
172 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
173 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
174 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
175 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
176 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
177 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
178 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
179 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
180 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
181 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
182 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
183 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
184 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
185 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
186 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
187 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
188 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
189 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
190 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
191 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
192 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
193 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
194 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
195};
196
ffbc8796
BW
197static int b4const_or_zero (int);
198static enum internal_test map_test_to_internal_test (enum rtx_code);
199static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
200static rtx gen_float_relational (enum rtx_code, rtx, rtx);
201static rtx gen_conditional_move (rtx);
202static rtx fixup_subreg_mem (rtx);
ffbc8796 203static struct machine_function * xtensa_init_machine_status (void);
6e5ff6e7 204static bool xtensa_return_in_msb (tree);
ffbc8796
BW
205static void printx (FILE *, signed int);
206static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
4c45af42 207static rtx xtensa_builtin_saveregs (void);
ffbc8796
BW
208static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
209 int) ATTRIBUTE_UNUSED;
210static void xtensa_select_rtx_section (enum machine_mode, rtx,
211 unsigned HOST_WIDE_INT);
212static bool xtensa_rtx_costs (rtx, int, int, int *);
c35d187f 213static tree xtensa_build_builtin_va_list (void);
4c45af42 214static bool xtensa_return_in_memory (tree, tree);
85d53c1d 215static tree xtensa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
b64a1b53 216
b64a1b53
RH
217static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
218 REG_ALLOC_ORDER;
219\f
03984308
BW
220
221/* This macro generates the assembly code for function exit,
222 on machines that need it. If FUNCTION_EPILOGUE is not defined
223 then individual return instructions are generated for each
224 return statement. Args are same as for FUNCTION_PROLOGUE. */
225
226#undef TARGET_ASM_FUNCTION_EPILOGUE
227#define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
228
229/* These hooks specify assembly directives for creating certain kinds
230 of integer object. */
231
232#undef TARGET_ASM_ALIGNED_SI_OP
233#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
234
b64a1b53
RH
235#undef TARGET_ASM_SELECT_RTX_SECTION
236#define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
03984308 237
3c50106f
RH
238#undef TARGET_RTX_COSTS
239#define TARGET_RTX_COSTS xtensa_rtx_costs
dcefdf67
RH
240#undef TARGET_ADDRESS_COST
241#define TARGET_ADDRESS_COST hook_int_rtx_0
3c50106f 242
c35d187f
RH
243#undef TARGET_BUILD_BUILTIN_VA_LIST
244#define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
245
4c45af42
KH
246#undef TARGET_PROMOTE_FUNCTION_ARGS
247#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
248#undef TARGET_PROMOTE_FUNCTION_RETURN
249#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
250#undef TARGET_PROMOTE_PROTOTYPES
251#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
252
4c45af42
KH
253#undef TARGET_RETURN_IN_MEMORY
254#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
42ba5130
RH
255#undef TARGET_SPLIT_COMPLEX_ARG
256#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
fe984136
RH
257#undef TARGET_MUST_PASS_IN_STACK
258#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
4c45af42
KH
259
260#undef TARGET_EXPAND_BUILTIN_SAVEREGS
261#define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
85d53c1d
RH
262#undef TARGET_GIMPLIFY_VA_ARG_EXPR
263#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
4c45af42 264
6e5ff6e7
BW
265#undef TARGET_RETURN_IN_MSB
266#define TARGET_RETURN_IN_MSB xtensa_return_in_msb
267
b64a1b53
RH
268struct gcc_target targetm = TARGET_INITIALIZER;
269\f
03984308
BW
270
271/*
272 * Functions to test Xtensa immediate operand validity.
273 */
274
275int
ffbc8796 276xtensa_b4constu (int v)
03984308
BW
277{
278 switch (v)
279 {
280 case 32768:
281 case 65536:
282 case 2:
283 case 3:
284 case 4:
285 case 5:
286 case 6:
287 case 7:
288 case 8:
289 case 10:
290 case 12:
291 case 16:
292 case 32:
293 case 64:
294 case 128:
295 case 256:
296 return 1;
297 }
298 return 0;
299}
300
301int
ffbc8796 302xtensa_simm8x256 (int v)
03984308
BW
303{
304 return (v & 255) == 0 && (v >= -32768 && v <= 32512);
305}
306
307int
ffbc8796 308xtensa_ai4const (int v)
03984308
BW
309{
310 return (v == -1 || (v >= 1 && v <= 15));
311}
312
313int
ffbc8796 314xtensa_simm7 (int v)
03984308
BW
315{
316 return v >= -32 && v <= 95;
317}
318
319int
ffbc8796 320xtensa_b4const (int v)
03984308
BW
321{
322 switch (v)
323 {
324 case -1:
325 case 1:
326 case 2:
327 case 3:
328 case 4:
329 case 5:
330 case 6:
331 case 7:
332 case 8:
333 case 10:
334 case 12:
335 case 16:
336 case 32:
337 case 64:
338 case 128:
339 case 256:
340 return 1;
341 }
342 return 0;
343}
344
345int
ffbc8796 346xtensa_simm8 (int v)
03984308
BW
347{
348 return v >= -128 && v <= 127;
349}
350
351int
ffbc8796 352xtensa_tp7 (int v)
03984308
BW
353{
354 return (v >= 7 && v <= 22);
355}
356
357int
ffbc8796 358xtensa_lsi4x4 (int v)
03984308
BW
359{
360 return (v & 3) == 0 && (v >= 0 && v <= 60);
361}
362
363int
ffbc8796 364xtensa_simm12b (int v)
03984308
BW
365{
366 return v >= -2048 && v <= 2047;
367}
368
369int
ffbc8796 370xtensa_uimm8 (int v)
03984308
BW
371{
372 return v >= 0 && v <= 255;
373}
374
375int
ffbc8796 376xtensa_uimm8x2 (int v)
03984308
BW
377{
378 return (v & 1) == 0 && (v >= 0 && v <= 510);
379}
380
381int
ffbc8796 382xtensa_uimm8x4 (int v)
03984308
BW
383{
384 return (v & 3) == 0 && (v >= 0 && v <= 1020);
385}
386
387
388/* This is just like the standard true_regnum() function except that it
638db43e 389 works even when reg_renumber is not initialized. */
03984308
BW
390
391int
ffbc8796 392xt_true_regnum (rtx x)
03984308
BW
393{
394 if (GET_CODE (x) == REG)
395 {
396 if (reg_renumber
397 && REGNO (x) >= FIRST_PSEUDO_REGISTER
398 && reg_renumber[REGNO (x)] >= 0)
399 return reg_renumber[REGNO (x)];
400 return REGNO (x);
401 }
402 if (GET_CODE (x) == SUBREG)
403 {
404 int base = xt_true_regnum (SUBREG_REG (x));
405 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
406 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
407 GET_MODE (SUBREG_REG (x)),
408 SUBREG_BYTE (x), GET_MODE (x));
409 }
410 return -1;
411}
412
413
414int
ffbc8796 415add_operand (rtx op, enum machine_mode mode)
03984308 416{
638db43e 417 if (GET_CODE (op) == CONST_INT)
f42f5a1b 418 return (xtensa_simm8 (INTVAL (op)) || xtensa_simm8x256 (INTVAL (op)));
03984308 419
638db43e 420 return register_operand (op, mode);
03984308
BW
421}
422
423
424int
ffbc8796 425arith_operand (rtx op, enum machine_mode mode)
03984308 426{
638db43e
BW
427 if (GET_CODE (op) == CONST_INT)
428 return xtensa_simm8 (INTVAL (op));
03984308 429
638db43e 430 return register_operand (op, mode);
03984308
BW
431}
432
433
434int
ffbc8796 435nonimmed_operand (rtx op, enum machine_mode mode)
03984308 436{
638db43e
BW
437 /* We cannot use the standard nonimmediate_operand() predicate because
438 it includes constant pool memory operands. */
03984308 439
638db43e
BW
440 if (memory_operand (op, mode))
441 return !constantpool_address_p (XEXP (op, 0));
03984308 442
638db43e 443 return register_operand (op, mode);
03984308
BW
444}
445
446
447int
ffbc8796 448mem_operand (rtx op, enum machine_mode mode)
03984308 449{
638db43e
BW
450 /* We cannot use the standard memory_operand() predicate because
451 it includes constant pool memory operands. */
03984308 452
638db43e
BW
453 if (memory_operand (op, mode))
454 return !constantpool_address_p (XEXP (op, 0));
03984308 455
638db43e 456 return FALSE;
03984308
BW
457}
458
459
460int
ffbc8796 461xtensa_valid_move (enum machine_mode mode, rtx *operands)
03984308 462{
a8cacfd2
BW
463 /* Either the destination or source must be a register, and the
464 MAC16 accumulator doesn't count. */
465
466 if (register_operand (operands[0], mode))
467 {
468 int dst_regnum = xt_true_regnum (operands[0]);
469
638db43e 470 /* The stack pointer can only be assigned with a MOVSP opcode. */
a8cacfd2
BW
471 if (dst_regnum == STACK_POINTER_REGNUM)
472 return (mode == SImode
473 && register_operand (operands[1], mode)
474 && !ACC_REG_P (xt_true_regnum (operands[1])));
475
476 if (!ACC_REG_P (dst_regnum))
477 return true;
478 }
3437320b 479 if (register_operand (operands[1], mode))
a8cacfd2
BW
480 {
481 int src_regnum = xt_true_regnum (operands[1]);
482 if (!ACC_REG_P (src_regnum))
483 return true;
484 }
03984308
BW
485 return FALSE;
486}
487
488
489int
ffbc8796 490mask_operand (rtx op, enum machine_mode mode)
03984308
BW
491{
492 if (GET_CODE (op) == CONST_INT)
493 return xtensa_mask_immediate (INTVAL (op));
494
495 return register_operand (op, mode);
496}
497
498
499int
ffbc8796 500extui_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
03984308
BW
501{
502 return ((GET_CODE (op) == CONST_INT)
503 && xtensa_mask_immediate ((1 << INTVAL (op)) - 1));
504}
505
506
507int
ffbc8796 508sext_operand (rtx op, enum machine_mode mode)
03984308
BW
509{
510 if (TARGET_SEXT)
511 return nonimmed_operand (op, mode);
512 return mem_operand (op, mode);
513}
514
515
516int
ffbc8796 517sext_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
03984308
BW
518{
519 return ((GET_CODE (op) == CONST_INT) && xtensa_tp7 (INTVAL (op) - 1));
520}
521
522
523int
ffbc8796 524lsbitnum_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
03984308
BW
525{
526 if (GET_CODE (op) == CONST_INT)
527 {
528 return (BITS_BIG_ENDIAN
529 ? (INTVAL (op) == BITS_PER_WORD-1)
530 : (INTVAL (op) == 0));
531 }
532 return FALSE;
533}
534
535
536static int
ffbc8796 537b4const_or_zero (int v)
03984308
BW
538{
539 if (v == 0)
540 return TRUE;
541 return xtensa_b4const (v);
542}
543
544
545int
ffbc8796 546branch_operand (rtx op, enum machine_mode mode)
03984308
BW
547{
548 if (GET_CODE (op) == CONST_INT)
549 return b4const_or_zero (INTVAL (op));
550
551 return register_operand (op, mode);
552}
553
554
555int
ffbc8796 556ubranch_operand (rtx op, enum machine_mode mode)
03984308
BW
557{
558 if (GET_CODE (op) == CONST_INT)
559 return xtensa_b4constu (INTVAL (op));
560
561 return register_operand (op, mode);
562}
563
564
565int
ffbc8796 566call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
03984308
BW
567{
568 if ((GET_CODE (op) == REG)
569 && (op != arg_pointer_rtx)
570 && ((REGNO (op) < FRAME_POINTER_REGNUM)
571 || (REGNO (op) > LAST_VIRTUAL_REGISTER)))
572 return TRUE;
573
574 if (CONSTANT_ADDRESS_P (op))
575 {
576 /* Direct calls only allowed to static functions with PIC. */
cadafd1f
BW
577 if (flag_pic)
578 {
579 tree callee, callee_sec, caller_sec;
580
f1dfe704
BW
581 if (GET_CODE (op) != SYMBOL_REF
582 || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
cadafd1f
BW
583 return FALSE;
584
585 /* Don't attempt a direct call if the callee is known to be in
586 a different section, since there's a good chance it will be
587 out of range. */
588
589 if (flag_function_sections
590 || DECL_ONE_ONLY (current_function_decl))
591 return FALSE;
592 caller_sec = DECL_SECTION_NAME (current_function_decl);
593 callee = SYMBOL_REF_DECL (op);
594 if (callee)
595 {
596 if (DECL_ONE_ONLY (callee))
597 return FALSE;
598 callee_sec = DECL_SECTION_NAME (callee);
599 if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
600 || (caller_sec != NULL_TREE
601 && strcmp (TREE_STRING_POINTER (caller_sec),
602 TREE_STRING_POINTER (callee_sec)) != 0))
603 return FALSE;
604 }
605 else if (caller_sec != NULL_TREE)
606 return FALSE;
607 }
608 return TRUE;
03984308
BW
609 }
610
611 return FALSE;
612}
613
614
615int
ffbc8796 616move_operand (rtx op, enum machine_mode mode)
03984308 617{
f42f5a1b
BW
618 if (register_operand (op, mode)
619 || memory_operand (op, mode))
03984308
BW
620 return TRUE;
621
633e4eb4
BW
622 switch (mode)
623 {
624 case DFmode:
625 case SFmode:
626 return TARGET_CONST16 && CONSTANT_P (op);
f42f5a1b 627
633e4eb4
BW
628 case DImode:
629 case SImode:
630 if (TARGET_CONST16)
631 return CONSTANT_P (op);
3bbc2af6 632 /* Fall through. */
03984308 633
633e4eb4
BW
634 case HImode:
635 case QImode:
633e4eb4
BW
636 if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
637 return TRUE;
638 break;
03984308 639
633e4eb4
BW
640 default:
641 break;
642 }
03984308
BW
643
644 return FALSE;
645}
646
647
648int
ffbc8796 649smalloffset_mem_p (rtx op)
03984308
BW
650{
651 if (GET_CODE (op) == MEM)
652 {
653 rtx addr = XEXP (op, 0);
654 if (GET_CODE (addr) == REG)
655 return REG_OK_FOR_BASE_P (addr);
656 if (GET_CODE (addr) == PLUS)
657 {
658 rtx offset = XEXP (addr, 0);
659 if (GET_CODE (offset) != CONST_INT)
660 offset = XEXP (addr, 1);
661 if (GET_CODE (offset) != CONST_INT)
662 return FALSE;
663 return xtensa_lsi4x4 (INTVAL (offset));
664 }
665 }
666 return FALSE;
667}
668
669
03984308 670int
ffbc8796 671constantpool_address_p (rtx addr)
03984308
BW
672{
673 rtx sym = addr;
674
675 if (GET_CODE (addr) == CONST)
676 {
677 rtx offset;
678
3bbc2af6 679 /* Only handle (PLUS (SYM, OFFSET)) form. */
03984308
BW
680 addr = XEXP (addr, 0);
681 if (GET_CODE (addr) != PLUS)
682 return FALSE;
683
3bbc2af6 684 /* Make sure the address is word aligned. */
03984308
BW
685 offset = XEXP (addr, 1);
686 if ((GET_CODE (offset) != CONST_INT)
687 || ((INTVAL (offset) & 3) != 0))
688 return FALSE;
689
690 sym = XEXP (addr, 0);
691 }
692
693 if ((GET_CODE (sym) == SYMBOL_REF)
694 && CONSTANT_POOL_ADDRESS_P (sym))
695 return TRUE;
696 return FALSE;
697}
698
699
700int
ffbc8796 701constantpool_mem_p (rtx op)
03984308
BW
702{
703 if (GET_CODE (op) == MEM)
704 return constantpool_address_p (XEXP (op, 0));
705 return FALSE;
706}
707
708
03984308
BW
709/* Accept the floating point constant 1 in the appropriate mode. */
710
711int
ffbc8796 712const_float_1_operand (rtx op, enum machine_mode mode)
03984308
BW
713{
714 REAL_VALUE_TYPE d;
715 static REAL_VALUE_TYPE onedf;
716 static REAL_VALUE_TYPE onesf;
717 static int one_initialized;
718
719 if ((GET_CODE (op) != CONST_DOUBLE)
720 || (mode != GET_MODE (op))
721 || (mode != DFmode && mode != SFmode))
722 return FALSE;
723
724 REAL_VALUE_FROM_CONST_DOUBLE (d, op);
725
726 if (! one_initialized)
727 {
728 onedf = REAL_VALUE_ATOF ("1.0", DFmode);
729 onesf = REAL_VALUE_ATOF ("1.0", SFmode);
730 one_initialized = TRUE;
731 }
732
733 if (mode == DFmode)
734 return REAL_VALUES_EQUAL (d, onedf);
735 else
736 return REAL_VALUES_EQUAL (d, onesf);
737}
738
739
740int
ffbc8796 741fpmem_offset_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
03984308
BW
742{
743 if (GET_CODE (op) == CONST_INT)
744 return xtensa_mem_offset (INTVAL (op), SFmode);
745 return 0;
746}
747
748
749void
ffbc8796 750xtensa_extend_reg (rtx dst, rtx src)
03984308
BW
751{
752 rtx temp = gen_reg_rtx (SImode);
753 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
754
3bbc2af6 755 /* Generate paradoxical subregs as needed so that the modes match. */
03984308
BW
756 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
757 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
758
759 emit_insn (gen_ashlsi3 (temp, src, shift));
760 emit_insn (gen_ashrsi3 (dst, temp, shift));
761}
762
763
03984308 764int
ffbc8796 765branch_operator (rtx x, enum machine_mode mode)
03984308
BW
766{
767 if (GET_MODE (x) != mode)
768 return FALSE;
769
770 switch (GET_CODE (x))
771 {
772 case EQ:
773 case NE:
774 case LT:
775 case GE:
776 return TRUE;
777 default:
778 break;
779 }
780 return FALSE;
781}
782
783
784int
ffbc8796 785ubranch_operator (rtx x, enum machine_mode mode)
03984308
BW
786{
787 if (GET_MODE (x) != mode)
788 return FALSE;
789
790 switch (GET_CODE (x))
791 {
792 case LTU:
793 case GEU:
794 return TRUE;
795 default:
796 break;
797 }
798 return FALSE;
799}
800
801
802int
ffbc8796 803boolean_operator (rtx x, enum machine_mode mode)
03984308
BW
804{
805 if (GET_MODE (x) != mode)
806 return FALSE;
807
808 switch (GET_CODE (x))
809 {
810 case EQ:
811 case NE:
812 return TRUE;
813 default:
814 break;
815 }
816 return FALSE;
817}
818
819
820int
ffbc8796 821xtensa_mask_immediate (int v)
03984308
BW
822{
823#define MAX_MASK_SIZE 16
824 int mask_size;
825
826 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
827 {
828 if ((v & 1) == 0)
829 return FALSE;
830 v = v >> 1;
831 if (v == 0)
832 return TRUE;
833 }
834
835 return FALSE;
836}
837
838
839int
ffbc8796 840xtensa_mem_offset (unsigned v, enum machine_mode mode)
03984308
BW
841{
842 switch (mode)
843 {
844 case BLKmode:
845 /* Handle the worst case for block moves. See xtensa_expand_block_move
846 where we emit an optimized block move operation if the block can be
847 moved in < "move_ratio" pieces. The worst case is when the block is
848 aligned but has a size of (3 mod 4) (does this happen?) so that the
638db43e 849 last piece requires a byte load/store. */
f42f5a1b
BW
850 return (xtensa_uimm8 (v)
851 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
03984308
BW
852
853 case QImode:
854 return xtensa_uimm8 (v);
855
856 case HImode:
857 return xtensa_uimm8x2 (v);
858
859 case DFmode:
860 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
861
862 default:
863 break;
864 }
865
866 return xtensa_uimm8x4 (v);
867}
868
869
ffbc8796 870/* Make normal rtx_code into something we can index from an array. */
03984308
BW
871
872static enum internal_test
ffbc8796 873map_test_to_internal_test (enum rtx_code test_code)
03984308
BW
874{
875 enum internal_test test = ITEST_MAX;
876
877 switch (test_code)
878 {
879 default: break;
880 case EQ: test = ITEST_EQ; break;
881 case NE: test = ITEST_NE; break;
882 case GT: test = ITEST_GT; break;
883 case GE: test = ITEST_GE; break;
884 case LT: test = ITEST_LT; break;
885 case LE: test = ITEST_LE; break;
886 case GTU: test = ITEST_GTU; break;
887 case GEU: test = ITEST_GEU; break;
888 case LTU: test = ITEST_LTU; break;
889 case LEU: test = ITEST_LEU; break;
890 }
891
892 return test;
893}
894
895
896/* Generate the code to compare two integer values. The return value is
638db43e 897 the comparison expression. */
03984308
BW
898
899static rtx
ffbc8796
BW
900gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
901 rtx cmp0, /* first operand to compare */
902 rtx cmp1, /* second operand to compare */
903 int *p_invert /* whether branch needs to reverse test */)
03984308 904{
ffbc8796
BW
905 struct cmp_info
906 {
03984308 907 enum rtx_code test_code; /* test code to use in insn */
ffbc8796 908 int (*const_range_p) (int); /* predicate function to check range */
03984308
BW
909 int const_add; /* constant to add (convert LE -> LT) */
910 int reverse_regs; /* reverse registers in test */
911 int invert_const; /* != 0 if invert value if cmp1 is constant */
912 int invert_reg; /* != 0 if invert value if cmp1 is register */
913 int unsignedp; /* != 0 for unsigned comparisons. */
914 };
915
916 static struct cmp_info info[ (int)ITEST_MAX ] = {
917
918 { EQ, b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */
919 { NE, b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */
920
921 { LT, b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */
922 { GE, b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */
923 { LT, b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */
924 { GE, b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */
925
926 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */
927 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */
928 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */
929 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */
930 };
931
932 enum internal_test test;
933 enum machine_mode mode;
934 struct cmp_info *p_info;
935
936 test = map_test_to_internal_test (test_code);
937 if (test == ITEST_MAX)
938 abort ();
939
940 p_info = &info[ (int)test ];
941
942 mode = GET_MODE (cmp0);
943 if (mode == VOIDmode)
944 mode = GET_MODE (cmp1);
945
946 /* Make sure we can handle any constants given to us. */
947 if (GET_CODE (cmp1) == CONST_INT)
948 {
949 HOST_WIDE_INT value = INTVAL (cmp1);
950 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
951
952 /* if the immediate overflows or does not fit in the immediate field,
953 spill it to a register */
954
955 if ((p_info->unsignedp ?
956 (uvalue + p_info->const_add > uvalue) :
957 (value + p_info->const_add > value)) != (p_info->const_add > 0))
958 {
959 cmp1 = force_reg (mode, cmp1);
960 }
961 else if (!(p_info->const_range_p) (value + p_info->const_add))
962 {
963 cmp1 = force_reg (mode, cmp1);
964 }
965 }
966 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
967 {
968 cmp1 = force_reg (mode, cmp1);
969 }
970
971 /* See if we need to invert the result. */
972 *p_invert = ((GET_CODE (cmp1) == CONST_INT)
973 ? p_info->invert_const
974 : p_info->invert_reg);
975
976 /* Comparison to constants, may involve adding 1 to change a LT into LE.
977 Comparison between two registers, may involve switching operands. */
978 if (GET_CODE (cmp1) == CONST_INT)
979 {
980 if (p_info->const_add != 0)
981 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
982
983 }
984 else if (p_info->reverse_regs)
985 {
986 rtx temp = cmp0;
987 cmp0 = cmp1;
988 cmp1 = temp;
989 }
990
1c563bed 991 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
03984308
BW
992}
993
994
995/* Generate the code to compare two float values. The return value is
638db43e 996 the comparison expression. */
03984308
BW
997
998static rtx
ffbc8796
BW
999gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
1000 rtx cmp0, /* first operand to compare */
1001 rtx cmp1 /* second operand to compare */)
03984308 1002{
ffbc8796 1003 rtx (*gen_fn) (rtx, rtx, rtx);
03984308
BW
1004 rtx brtmp;
1005 int reverse_regs, invert;
1006
1007 switch (test_code)
1008 {
1009 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
1010 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
1011 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
1012 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
1013 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
1014 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
633e4eb4 1015 default:
1c563bed 1016 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
03984308
BW
1017 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
1018 }
1019
1020 if (reverse_regs)
1021 {
1022 rtx temp = cmp0;
1023 cmp0 = cmp1;
1024 cmp1 = temp;
1025 }
1026
1027 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
1028 emit_insn (gen_fn (brtmp, cmp0, cmp1));
1029
1c563bed 1030 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
03984308
BW
1031}
1032
1033
1034void
ffbc8796 1035xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
03984308
BW
1036{
1037 enum cmp_type type = branch_type;
1038 rtx cmp0 = branch_cmp[0];
1039 rtx cmp1 = branch_cmp[1];
1040 rtx cmp;
1041 int invert;
1042 rtx label1, label2;
1043
1044 switch (type)
1045 {
1046 case CMP_DF:
1047 default:
1c563bed 1048 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
03984308
BW
1049
1050 case CMP_SI:
1051 invert = FALSE;
1052 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
1053 break;
1054
1055 case CMP_SF:
1056 if (!TARGET_HARD_FLOAT)
1c563bed 1057 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
03984308
BW
1058 invert = FALSE;
1059 cmp = gen_float_relational (test_code, cmp0, cmp1);
1060 break;
1061 }
1062
1063 /* Generate the branch. */
1064
1065 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
1066 label2 = pc_rtx;
1067
1068 if (invert)
1069 {
1070 label2 = label1;
1071 label1 = pc_rtx;
1072 }
1073
1074 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1075 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
1076 label1,
1077 label2)));
1078}
1079
1080
1081static rtx
ffbc8796 1082gen_conditional_move (rtx cmp)
03984308
BW
1083{
1084 enum rtx_code code = GET_CODE (cmp);
1085 rtx op0 = branch_cmp[0];
1086 rtx op1 = branch_cmp[1];
1087
1088 if (branch_type == CMP_SI)
1089 {
1090 /* Jump optimization calls get_condition() which canonicalizes
1091 comparisons like (GE x <const>) to (GT x <const-1>).
1092 Transform those comparisons back to GE, since that is the
1093 comparison supported in Xtensa. We shouldn't have to
1094 transform <LE x const> comparisons, because neither
1095 xtensa_expand_conditional_branch() nor get_condition() will
638db43e 1096 produce them. */
03984308
BW
1097
1098 if ((code == GT) && (op1 == constm1_rtx))
1099 {
1100 code = GE;
1101 op1 = const0_rtx;
1102 }
1c563bed 1103 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
03984308
BW
1104
1105 if (boolean_operator (cmp, VOIDmode))
1106 {
3bbc2af6 1107 /* Swap the operands to make const0 second. */
03984308
BW
1108 if (op0 == const0_rtx)
1109 {
1110 op0 = op1;
1111 op1 = const0_rtx;
1112 }
1113
3bbc2af6 1114 /* If not comparing against zero, emit a comparison (subtract). */
03984308
BW
1115 if (op1 != const0_rtx)
1116 {
1117 op0 = expand_binop (SImode, sub_optab, op0, op1,
1118 0, 0, OPTAB_LIB_WIDEN);
1119 op1 = const0_rtx;
1120 }
1121 }
1122 else if (branch_operator (cmp, VOIDmode))
1123 {
3bbc2af6 1124 /* Swap the operands to make const0 second. */
03984308
BW
1125 if (op0 == const0_rtx)
1126 {
1127 op0 = op1;
1128 op1 = const0_rtx;
1129
1130 switch (code)
1131 {
1132 case LT: code = GE; break;
1133 case GE: code = LT; break;
1134 default: abort ();
1135 }
1136 }
1137
1138 if (op1 != const0_rtx)
1139 return 0;
1140 }
1141 else
1142 return 0;
1143
1c563bed 1144 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
03984308
BW
1145 }
1146
1147 if (TARGET_HARD_FLOAT && (branch_type == CMP_SF))
1148 return gen_float_relational (code, op0, op1);
1149
1150 return 0;
1151}
1152
1153
1154int
ffbc8796 1155xtensa_expand_conditional_move (rtx *operands, int isflt)
03984308
BW
1156{
1157 rtx cmp;
ffbc8796 1158 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
03984308
BW
1159
1160 if (!(cmp = gen_conditional_move (operands[1])))
1161 return 0;
1162
1163 if (isflt)
1164 gen_fn = (branch_type == CMP_SI
1165 ? gen_movsfcc_internal0
1166 : gen_movsfcc_internal1);
1167 else
1168 gen_fn = (branch_type == CMP_SI
1169 ? gen_movsicc_internal0
1170 : gen_movsicc_internal1);
1171
1172 emit_insn (gen_fn (operands[0], XEXP (cmp, 0),
1173 operands[2], operands[3], cmp));
1174 return 1;
1175}
1176
1177
1178int
ffbc8796 1179xtensa_expand_scc (rtx *operands)
03984308
BW
1180{
1181 rtx dest = operands[0];
1182 rtx cmp = operands[1];
1183 rtx one_tmp, zero_tmp;
ffbc8796 1184 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
03984308
BW
1185
1186 if (!(cmp = gen_conditional_move (cmp)))
1187 return 0;
1188
1189 one_tmp = gen_reg_rtx (SImode);
1190 zero_tmp = gen_reg_rtx (SImode);
1191 emit_insn (gen_movsi (one_tmp, const_true_rtx));
1192 emit_insn (gen_movsi (zero_tmp, const0_rtx));
1193
1194 gen_fn = (branch_type == CMP_SI
1195 ? gen_movsicc_internal0
1196 : gen_movsicc_internal1);
1197 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
1198 return 1;
1199}
1200
1201
633e4eb4
BW
1202/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
1203 for the output, i.e., the input operands are twice as big as MODE. */
1204
1205void
ffbc8796 1206xtensa_split_operand_pair (rtx operands[4], enum machine_mode mode)
633e4eb4
BW
1207{
1208 switch (GET_CODE (operands[1]))
1209 {
1210 case REG:
1211 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
1212 operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
1213 break;
1214
1215 case MEM:
1216 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
1217 operands[2] = adjust_address (operands[1], mode, 0);
1218 break;
1219
1220 case CONST_INT:
1221 case CONST_DOUBLE:
1222 split_double (operands[1], &operands[2], &operands[3]);
1223 break;
1224
1225 default:
1226 abort ();
1227 }
1228
1229 switch (GET_CODE (operands[0]))
1230 {
1231 case REG:
1232 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
1233 operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
1234 break;
1235
1236 case MEM:
1237 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
1238 operands[0] = adjust_address (operands[0], mode, 0);
1239 break;
1240
1241 default:
1242 abort ();
1243 }
1244}
1245
1246
03984308 1247/* Emit insns to move operands[1] into operands[0].
03984308
BW
1248 Return 1 if we have written out everything that needs to be done to
1249 do the move. Otherwise, return 0 and the caller will emit the move
1250 normally. */
1251
1252int
ffbc8796 1253xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
03984308
BW
1254{
1255 if (CONSTANT_P (operands[1])
03984308
BW
1256 && (GET_CODE (operands[1]) != CONST_INT
1257 || !xtensa_simm12b (INTVAL (operands[1]))))
1258 {
f42f5a1b
BW
1259 if (!TARGET_CONST16)
1260 operands[1] = force_const_mem (SImode, operands[1]);
1261
1262 /* PC-relative loads are always SImode, and CONST16 is only
1263 supported in the movsi pattern, so add a SUBREG for any other
1264 (smaller) mode. */
1265
1266 if (mode != SImode)
1267 {
1268 if (register_operand (operands[0], mode))
1269 {
1270 operands[0] = simplify_gen_subreg (SImode, operands[0], mode, 0);
1271 emit_move_insn (operands[0], operands[1]);
1272 return 1;
1273 }
1274 else
1275 {
1276 operands[1] = force_reg (SImode, operands[1]);
1277 operands[1] = gen_lowpart_SUBREG (mode, operands[1]);
1278 }
1279 }
03984308
BW
1280 }
1281
997b8b4d
BW
1282 if (!(reload_in_progress | reload_completed)
1283 && !xtensa_valid_move (mode, operands))
1284 operands[1] = force_reg (mode, operands[1]);
03984308 1285
997b8b4d 1286 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
03984308
BW
1287
1288 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
638db43e
BW
1289 instruction won't be recognized after reload, so we remove the
1290 subreg and adjust mem accordingly. */
03984308
BW
1291 if (reload_in_progress)
1292 {
1293 operands[0] = fixup_subreg_mem (operands[0]);
1294 operands[1] = fixup_subreg_mem (operands[1]);
1295 }
1296 return 0;
1297}
1298
f42f5a1b 1299
03984308 1300static rtx
ffbc8796 1301fixup_subreg_mem (rtx x)
03984308
BW
1302{
1303 if (GET_CODE (x) == SUBREG
1304 && GET_CODE (SUBREG_REG (x)) == REG
1305 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1306 {
1307 rtx temp =
1308 gen_rtx_SUBREG (GET_MODE (x),
1309 reg_equiv_mem [REGNO (SUBREG_REG (x))],
1310 SUBREG_BYTE (x));
1311 x = alter_subreg (&temp);
1312 }
1313 return x;
1314}
1315
1316
997b8b4d
BW
1317/* Check if an incoming argument in a7 is expected to be used soon and
1318 if OPND is a register or register pair that includes a7. If so,
1319 create a new pseudo and copy a7 into that pseudo at the very
1320 beginning of the function, followed by the special "set_frame_ptr"
1321 unspec_volatile insn. The return value is either the original
1322 operand, if it is not a7, or the new pseudo containing a copy of
1323 the incoming argument. This is necessary because the register
1324 allocator will ignore conflicts with a7 and may either assign some
1325 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1326 the incoming argument in a7. By copying the argument out of a7 as
1327 the very first thing, and then immediately following that with an
1328 unspec_volatile to keep the scheduler away, we should avoid any
1329 problems. Putting the set_frame_ptr insn at the beginning, with
1330 only the a7 copy before it, also makes it easier for the prologue
1331 expander to initialize the frame pointer after the a7 copy and to
1332 fix up the a7 copy to use the stack pointer instead of the frame
1333 pointer. */
58db834b 1334
997b8b4d
BW
1335rtx
1336xtensa_copy_incoming_a7 (rtx opnd)
58db834b 1337{
997b8b4d
BW
1338 rtx entry_insns = 0;
1339 rtx reg, tmp;
1340 enum machine_mode mode;
1341
1342 if (!cfun->machine->need_a7_copy)
1343 return opnd;
1344
1345 /* This function should never be called again once a7 has been copied. */
1346 if (cfun->machine->set_frame_ptr_insn)
1347 abort ();
1348
1349 mode = GET_MODE (opnd);
1350
1351 /* The operand using a7 may come in a later instruction, so just return
1352 the original operand if it doesn't use a7. */
1353 reg = opnd;
1354 if (GET_CODE (reg) == SUBREG)
58db834b 1355 {
997b8b4d
BW
1356 if (SUBREG_BYTE (reg) != 0)
1357 abort ();
1358 reg = SUBREG_REG (reg);
1359 }
1360 if (GET_CODE (reg) != REG
1361 || REGNO (reg) > A7_REG
1362 || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
1363 return opnd;
e6aecf8e 1364
997b8b4d
BW
1365 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1366 if (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 != A7_REG)
1367 abort ();
58db834b 1368
997b8b4d 1369 cfun->machine->need_a7_copy = false;
58db834b 1370
997b8b4d
BW
1371 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1372 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
58db834b 1373
997b8b4d
BW
1374 push_to_sequence (entry_insns);
1375 tmp = gen_reg_rtx (mode);
58db834b 1376
997b8b4d
BW
1377 switch (mode)
1378 {
1379 case DFmode:
1380 case DImode:
1381 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1382 gen_rtx_REG (SImode, A7_REG - 1)));
1383 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1384 gen_raw_REG (SImode, A7_REG)));
1385 break;
1386 case SFmode:
1387 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1388 break;
1389 case SImode:
1390 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1391 break;
1392 case HImode:
1393 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1394 break;
1395 case QImode:
1396 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1397 break;
1398 default:
1399 abort ();
58db834b
BW
1400 }
1401
997b8b4d
BW
1402 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1403 entry_insns = get_insns ();
1404 end_sequence ();
1405
1406 if (cfun->machine->vararg_a7)
1407 {
1408 /* This is called from within builtin_savereg, so we're already
1409 inside a start_sequence that will be placed at the start of
1410 the function. */
1411 emit_insn (entry_insns);
1412 }
1413 else
1414 {
1415 /* Put entry_insns after the NOTE that starts the function. If
1416 this is inside a start_sequence, make the outer-level insn
1417 chain current, so the code is placed at the start of the
1418 function. */
1419 push_topmost_sequence ();
1420 emit_insn_after (entry_insns, get_insns ());
1421 pop_topmost_sequence ();
1422 }
1423
1424 return tmp;
58db834b
BW
1425}
1426
1427
03984308
BW
1428/* Try to expand a block move operation to an RTL block move instruction.
1429 If not optimizing or if the block size is not a constant or if the
1430 block is small, the expansion fails and GCC falls back to calling
1431 memcpy().
1432
1433 operands[0] is the destination
1434 operands[1] is the source
1435 operands[2] is the length
1436 operands[3] is the alignment */
1437
1438int
ffbc8796 1439xtensa_expand_block_move (rtx *operands)
03984308 1440{
7eda7cda
RH
1441 static const enum machine_mode mode_from_align[] =
1442 {
1443 VOIDmode, QImode, HImode, VOIDmode, SImode,
1444 };
1445
1446 rtx dst_mem = operands[0];
1447 rtx src_mem = operands[1];
1448 HOST_WIDE_INT bytes, align;
03984308 1449 int num_pieces, move_ratio;
7eda7cda
RH
1450 rtx temp[2];
1451 enum machine_mode mode[2];
1452 int amount[2];
1453 bool active[2];
1454 int phase = 0;
1455 int next;
1456 int offset_ld = 0;
1457 int offset_st = 0;
1458 rtx x;
03984308 1459
3bbc2af6 1460 /* If this is not a fixed size move, just call memcpy. */
03984308
BW
1461 if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1462 return 0;
1463
7eda7cda
RH
1464 bytes = INTVAL (operands[2]);
1465 align = INTVAL (operands[3]);
1466
3bbc2af6 1467 /* Anything to move? */
03984308 1468 if (bytes <= 0)
7eda7cda 1469 return 0;
03984308
BW
1470
1471 if (align > MOVE_MAX)
1472 align = MOVE_MAX;
1473
3bbc2af6 1474 /* Decide whether to expand inline based on the optimization level. */
03984308
BW
1475 move_ratio = 4;
1476 if (optimize > 2)
1477 move_ratio = LARGEST_MOVE_RATIO;
3bbc2af6 1478 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */
7eda7cda 1479 if (num_pieces > move_ratio)
03984308
BW
1480 return 0;
1481
7eda7cda
RH
1482 x = XEXP (dst_mem, 0);
1483 if (!REG_P (x))
1484 {
1485 x = force_reg (Pmode, x);
1486 dst_mem = replace_equiv_address (dst_mem, x);
1487 }
03984308 1488
7eda7cda
RH
1489 x = XEXP (src_mem, 0);
1490 if (!REG_P (x))
1491 {
1492 x = force_reg (Pmode, x);
1493 src_mem = replace_equiv_address (src_mem, x);
1494 }
03984308 1495
7eda7cda 1496 active[0] = active[1] = false;
03984308 1497
7eda7cda 1498 do
03984308 1499 {
7eda7cda
RH
1500 next = phase;
1501 phase ^= 1;
03984308 1502
7eda7cda 1503 if (bytes > 0)
03984308 1504 {
7eda7cda 1505 int next_amount;
03984308 1506
7eda7cda
RH
1507 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1508 next_amount = MIN (next_amount, align);
03984308 1509
7eda7cda
RH
1510 amount[next] = next_amount;
1511 mode[next] = mode_from_align[next_amount];
1512 temp[next] = gen_reg_rtx (mode[next]);
03984308 1513
7eda7cda
RH
1514 x = adjust_address (src_mem, mode[next], offset_ld);
1515 emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
03984308 1516
7eda7cda
RH
1517 offset_ld += next_amount;
1518 bytes -= next_amount;
1519 active[next] = true;
1520 }
03984308 1521
7eda7cda
RH
1522 if (active[phase])
1523 {
1524 active[phase] = false;
1525
1526 x = adjust_address (dst_mem, mode[phase], offset_st);
1527 emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
03984308 1528
7eda7cda
RH
1529 offset_st += amount[phase];
1530 }
03984308 1531 }
7eda7cda 1532 while (active[next]);
03984308 1533
7eda7cda 1534 return 1;
03984308
BW
1535}
1536
1537
1538void
ffbc8796 1539xtensa_expand_nonlocal_goto (rtx *operands)
03984308
BW
1540{
1541 rtx goto_handler = operands[1];
1542 rtx containing_fp = operands[3];
1543
3bbc2af6
KH
1544 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1545 is too big to generate in-line. */
03984308
BW
1546
1547 if (GET_CODE (containing_fp) != REG)
1548 containing_fp = force_reg (Pmode, containing_fp);
1549
1550 goto_handler = replace_rtx (copy_rtx (goto_handler),
1551 virtual_stack_vars_rtx,
1552 containing_fp);
1553
1554 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1555 0, VOIDmode, 2,
1556 containing_fp, Pmode,
1557 goto_handler, Pmode);
1558}
1559
1560
e2500fed 1561static struct machine_function *
ffbc8796 1562xtensa_init_machine_status (void)
03984308 1563{
e2500fed 1564 return ggc_alloc_cleared (sizeof (struct machine_function));
03984308
BW
1565}
1566
1567
1568void
ffbc8796 1569xtensa_setup_frame_addresses (void)
03984308 1570{
638db43e 1571 /* Set flag to cause FRAME_POINTER_REQUIRED to be set. */
03984308
BW
1572 cfun->machine->accesses_prev_frame = 1;
1573
1574 emit_library_call
1575 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1576 0, VOIDmode, 0);
1577}
1578
1579
638db43e
BW
1580/* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1581 a comment showing where the end of the loop is. However, if there is a
03984308 1582 label or a branch at the end of the loop then we need to place a nop
638db43e 1583 there. If the loop ends with a label we need the nop so that branches
839a4992
KH
1584 targeting that label will target the nop (and thus remain in the loop),
1585 instead of targeting the instruction after the loop (and thus exiting
638db43e 1586 the loop). If the loop ends with a branch, we need the nop in case the
839a4992 1587 branch is targeting a location inside the loop. When the branch
03984308
BW
1588 executes it will cause the loop count to be decremented even if it is
1589 taken (because it is the last instruction in the loop), so we need to
1590 nop after the branch to prevent the loop count from being decremented
638db43e 1591 when the branch is taken. */
03984308
BW
1592
1593void
ffbc8796 1594xtensa_emit_loop_end (rtx insn, rtx *operands)
03984308
BW
1595{
1596 char done = 0;
1597
1598 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1599 {
1600 switch (GET_CODE (insn))
1601 {
1602 case NOTE:
1603 case BARRIER:
1604 break;
1605
1606 case CODE_LABEL:
0bd0703d 1607 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
03984308
BW
1608 done = 1;
1609 break;
1610
1611 default:
1612 {
1613 rtx body = PATTERN (insn);
1614
1615 if (GET_CODE (body) == JUMP_INSN)
1616 {
0bd0703d 1617 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
03984308
BW
1618 done = 1;
1619 }
1620 else if ((GET_CODE (body) != USE)
1621 && (GET_CODE (body) != CLOBBER))
1622 done = 1;
1623 }
1624 break;
1625 }
1626 }
1627
1628 output_asm_insn ("# loop end for %0", operands);
1629}
1630
1631
1632char *
ffbc8796 1633xtensa_emit_call (int callop, rtx *operands)
03984308 1634{
b64a1b53 1635 static char result[64];
03984308
BW
1636 rtx tgt = operands[callop];
1637
1638 if (GET_CODE (tgt) == CONST_INT)
1d0ea52e 1639 sprintf (result, "call8\t0x%lx", INTVAL (tgt));
03984308
BW
1640 else if (register_operand (tgt, VOIDmode))
1641 sprintf (result, "callx8\t%%%d", callop);
1642 else
1643 sprintf (result, "call8\t%%%d", callop);
1644
1645 return result;
1646}
1647
1648
b0c6e48f 1649/* Return the debugger register number to use for 'regno'. */
03984308
BW
1650
1651int
ffbc8796 1652xtensa_dbx_register_number (int regno)
03984308
BW
1653{
1654 int first = -1;
633e4eb4
BW
1655
1656 if (GP_REG_P (regno))
1657 {
1658 regno -= GP_REG_FIRST;
1659 first = 0;
1660 }
1661 else if (BR_REG_P (regno))
1662 {
1663 regno -= BR_REG_FIRST;
1664 first = 16;
1665 }
1666 else if (FP_REG_P (regno))
1667 {
1668 regno -= FP_REG_FIRST;
b0c6e48f 1669 first = 48;
633e4eb4 1670 }
03984308
BW
1671 else if (ACC_REG_P (regno))
1672 {
b0c6e48f
BW
1673 first = 0x200; /* Start of Xtensa special registers. */
1674 regno = 16; /* ACCLO is special register 16. */
03984308
BW
1675 }
1676
1677 /* When optimizing, we sometimes get asked about pseudo-registers
638db43e 1678 that don't represent hard registers. Return 0 for these. */
03984308
BW
1679 if (first == -1)
1680 return 0;
1681
1682 return first + regno;
1683}
1684
1685
1686/* Argument support functions. */
1687
1688/* Initialize CUMULATIVE_ARGS for a function. */
1689
1690void
997b8b4d 1691init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
03984308
BW
1692{
1693 cum->arg_words = 0;
997b8b4d 1694 cum->incoming = incoming;
03984308
BW
1695}
1696
ffbc8796 1697
03984308
BW
1698/* Advance the argument to the next argument position. */
1699
1700void
ffbc8796 1701function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
03984308
BW
1702{
1703 int words, max;
1704 int *arg_words;
1705
1706 arg_words = &cum->arg_words;
1707 max = MAX_ARGS_IN_REGISTERS;
1708
1709 words = (((mode != BLKmode)
1710 ? (int) GET_MODE_SIZE (mode)
1711 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1712
85d91d5b
BW
1713 if (*arg_words < max
1714 && (targetm.calls.must_pass_in_stack (mode, type)
1715 || *arg_words + words > max))
03984308
BW
1716 *arg_words = max;
1717
1718 *arg_words += words;
1719}
1720
1721
1722/* Return an RTL expression containing the register for the given mode,
368ebcd6 1723 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
ffbc8796 1724 if this is an incoming argument to the current function. */
03984308
BW
1725
1726rtx
ffbc8796
BW
1727function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1728 int incoming_p)
03984308
BW
1729{
1730 int regbase, words, max;
1731 int *arg_words;
1732 int regno;
03984308
BW
1733
1734 arg_words = &cum->arg_words;
1735 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
1736 max = MAX_ARGS_IN_REGISTERS;
1737
1738 words = (((mode != BLKmode)
1739 ? (int) GET_MODE_SIZE (mode)
1740 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1741
1742 if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
822e895c
BW
1743 {
1744 int align = TYPE_ALIGN (type) / BITS_PER_WORD;
1745 *arg_words = (*arg_words + align - 1) & -align;
1746 }
03984308
BW
1747
1748 if (*arg_words + words > max)
1749 return (rtx)0;
1750
1751 regno = regbase + *arg_words;
03984308 1752
997b8b4d
BW
1753 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
1754 cfun->machine->need_a7_copy = true;
03984308 1755
997b8b4d 1756 return gen_rtx_REG (mode, regno);
03984308
BW
1757}
1758
1759
6e5ff6e7
BW
1760static bool
1761xtensa_return_in_msb (tree valtype)
1762{
1763 return (TARGET_BIG_ENDIAN
1764 && AGGREGATE_TYPE_P (valtype)
1765 && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
1766}
1767
1768
03984308 1769void
ffbc8796 1770override_options (void)
03984308
BW
1771{
1772 int regno;
1773 enum machine_mode mode;
1774
1775 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
1776 error ("boolean registers required for the floating-point option");
1777
3bbc2af6 1778 /* Set up the tables of ld/st opcode names for block moves. */
03984308
BW
1779 xtensa_ld_opcodes[(int) SImode] = "l32i";
1780 xtensa_ld_opcodes[(int) HImode] = "l16ui";
1781 xtensa_ld_opcodes[(int) QImode] = "l8ui";
1782 xtensa_st_opcodes[(int) SImode] = "s32i";
1783 xtensa_st_opcodes[(int) HImode] = "s16i";
1784 xtensa_st_opcodes[(int) QImode] = "s8i";
1785
1786 xtensa_char_to_class['q'] = SP_REG;
1787 xtensa_char_to_class['a'] = GR_REGS;
1788 xtensa_char_to_class['b'] = ((TARGET_BOOLEANS) ? BR_REGS : NO_REGS);
1789 xtensa_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
1790 xtensa_char_to_class['A'] = ((TARGET_MAC16) ? ACC_REG : NO_REGS);
1791 xtensa_char_to_class['B'] = ((TARGET_SEXT) ? GR_REGS : NO_REGS);
1792 xtensa_char_to_class['C'] = ((TARGET_MUL16) ? GR_REGS: NO_REGS);
1793 xtensa_char_to_class['D'] = ((TARGET_DENSITY) ? GR_REGS: NO_REGS);
1794 xtensa_char_to_class['d'] = ((TARGET_DENSITY) ? AR_REGS: NO_REGS);
f42f5a1b 1795 xtensa_char_to_class['W'] = ((TARGET_CONST16) ? GR_REGS: NO_REGS);
03984308 1796
638db43e 1797 /* Set up array giving whether a given register can hold a given mode. */
03984308
BW
1798 for (mode = VOIDmode;
1799 mode != MAX_MACHINE_MODE;
1800 mode = (enum machine_mode) ((int) mode + 1))
1801 {
1802 int size = GET_MODE_SIZE (mode);
1803 enum mode_class class = GET_MODE_CLASS (mode);
1804
1805 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1806 {
1807 int temp;
1808
1809 if (ACC_REG_P (regno))
f42f5a1b
BW
1810 temp = (TARGET_MAC16
1811 && (class == MODE_INT) && (size <= UNITS_PER_WORD));
03984308
BW
1812 else if (GP_REG_P (regno))
1813 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
1814 else if (FP_REG_P (regno))
1815 temp = (TARGET_HARD_FLOAT && (mode == SFmode));
1816 else if (BR_REG_P (regno))
1817 temp = (TARGET_BOOLEANS && (mode == CCmode));
1818 else
1819 temp = FALSE;
1820
1821 xtensa_hard_regno_mode_ok[(int) mode][regno] = temp;
1822 }
1823 }
1824
1825 init_machine_status = xtensa_init_machine_status;
03984308 1826
f42f5a1b
BW
1827 /* Check PIC settings. PIC is only supported when using L32R
1828 instructions, and some targets need to always use PIC. */
1829 if (flag_pic && TARGET_CONST16)
1830 error ("-f%s is not supported with CONST16 instructions",
1831 (flag_pic > 1 ? "PIC" : "pic"));
1832 else if (XTENSA_ALWAYS_PIC)
1833 {
1834 if (TARGET_CONST16)
1835 error ("PIC is required but not supported with CONST16 instructions");
1836 flag_pic = 1;
1837 }
1838 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
1839 if (flag_pic > 1)
03984308
BW
1840 flag_pic = 1;
1841}
1842
1843
1844/* A C compound statement to output to stdio stream STREAM the
1845 assembler syntax for an instruction operand X. X is an RTL
1846 expression.
1847
1848 CODE is a value that can be used to specify one of several ways
1849 of printing the operand. It is used when identical operands
1850 must be printed differently depending on the context. CODE
1851 comes from the '%' specification that was used to request
1852 printing of the operand. If the specification was just '%DIGIT'
1853 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
1854 is the ASCII code for LTR.
1855
1856 If X is a register, this macro should print the register's name.
1857 The names can be found in an array 'reg_names' whose type is
1858 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
1859
1860 When the machine description has a specification '%PUNCT' (a '%'
1861 followed by a punctuation character), this macro is called with
1862 a null pointer for X and the punctuation character for CODE.
1863
1864 'a', 'c', 'l', and 'n' are reserved.
633e4eb4 1865
03984308
BW
1866 The Xtensa specific codes are:
1867
1868 'd' CONST_INT, print as signed decimal
1869 'x' CONST_INT, print as signed hexadecimal
1870 'K' CONST_INT, print number of bits in mask for EXTUI
1871 'R' CONST_INT, print (X & 0x1f)
1872 'L' CONST_INT, print ((32 - X) & 0x1f)
1873 'D' REG, print second register of double-word register operand
1874 'N' MEM, print address of next word following a memory operand
1875 'v' MEM, if memory reference is volatile, output a MEMW before it
f42f5a1b
BW
1876 't' any constant, add "@h" suffix for top 16 bits
1877 'b' any constant, add "@l" suffix for bottom 16 bits
03984308
BW
1878*/
1879
1880static void
ffbc8796 1881printx (FILE *file, signed int val)
03984308 1882{
ffbc8796 1883 /* Print a hexadecimal value in a nice way. */
03984308
BW
1884 if ((val > -0xa) && (val < 0xa))
1885 fprintf (file, "%d", val);
1886 else if (val < 0)
1887 fprintf (file, "-0x%x", -val);
1888 else
1889 fprintf (file, "0x%x", val);
1890}
1891
1892
1893void
ffbc8796 1894print_operand (FILE *file, rtx x, int letter)
03984308 1895{
f42f5a1b 1896 if (!x)
03984308
BW
1897 error ("PRINT_OPERAND null pointer");
1898
f42f5a1b 1899 switch (letter)
03984308 1900 {
f42f5a1b
BW
1901 case 'D':
1902 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
1903 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
1904 else
1905 output_operand_lossage ("invalid %%D value");
1906 break;
03984308 1907
f42f5a1b
BW
1908 case 'v':
1909 if (GET_CODE (x) == MEM)
1910 {
1911 /* For a volatile memory reference, emit a MEMW before the
1912 load or store. */
7a29f483 1913 if (MEM_VOLATILE_P (x))
f42f5a1b
BW
1914 fprintf (file, "memw\n\t");
1915 }
1916 else
1917 output_operand_lossage ("invalid %%v value");
1918 break;
03984308 1919
f42f5a1b
BW
1920 case 'N':
1921 if (GET_CODE (x) == MEM
1922 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
1923 {
1924 x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
1925 output_address (XEXP (x, 0));
1926 }
1927 else
1928 output_operand_lossage ("invalid %%N value");
1929 break;
03984308 1930
f42f5a1b
BW
1931 case 'K':
1932 if (GET_CODE (x) == CONST_INT)
03984308 1933 {
f42f5a1b
BW
1934 int num_bits = 0;
1935 unsigned val = INTVAL (x);
1936 while (val & 1)
1937 {
1938 num_bits += 1;
1939 val = val >> 1;
1940 }
1941 if ((val != 0) || (num_bits == 0) || (num_bits > 16))
1942 fatal_insn ("invalid mask", x);
03984308 1943
f42f5a1b
BW
1944 fprintf (file, "%d", num_bits);
1945 }
1946 else
1947 output_operand_lossage ("invalid %%K value");
1948 break;
03984308 1949
f42f5a1b
BW
1950 case 'L':
1951 if (GET_CODE (x) == CONST_INT)
1952 fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f);
1953 else
1954 output_operand_lossage ("invalid %%L value");
1955 break;
03984308 1956
f42f5a1b
BW
1957 case 'R':
1958 if (GET_CODE (x) == CONST_INT)
1959 fprintf (file, "%ld", INTVAL (x) & 0x1f);
1960 else
1961 output_operand_lossage ("invalid %%R value");
1962 break;
03984308 1963
f42f5a1b
BW
1964 case 'x':
1965 if (GET_CODE (x) == CONST_INT)
1966 printx (file, INTVAL (x));
1967 else
1968 output_operand_lossage ("invalid %%x value");
1969 break;
03984308 1970
f42f5a1b
BW
1971 case 'd':
1972 if (GET_CODE (x) == CONST_INT)
1973 fprintf (file, "%ld", INTVAL (x));
1974 else
1975 output_operand_lossage ("invalid %%d value");
1976 break;
03984308 1977
f42f5a1b
BW
1978 case 't':
1979 case 'b':
1980 if (GET_CODE (x) == CONST_INT)
1981 {
1982 printx (file, INTVAL (x));
1983 fputs (letter == 't' ? "@h" : "@l", file);
1984 }
1985 else if (GET_CODE (x) == CONST_DOUBLE)
1986 {
1987 REAL_VALUE_TYPE r;
1988 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1989 if (GET_MODE (x) == SFmode)
1990 {
1991 long l;
1992 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1993 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
1994 }
1995 else
1996 output_operand_lossage ("invalid %%t/%%b value");
1997 }
1998 else if (GET_CODE (x) == CONST)
1999 {
2000 /* X must be a symbolic constant on ELF. Write an expression
2001 suitable for 'const16' that sets the high or low 16 bits. */
2002 if (GET_CODE (XEXP (x, 0)) != PLUS
2003 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2004 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2005 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2006 output_operand_lossage ("invalid %%t/%%b value");
2007 print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2008 fputs (letter == 't' ? "@h" : "@l", file);
2009 /* There must be a non-alphanumeric character between 'h' or 'l'
2010 and the number. The '-' is added by print_operand() already. */
2011 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2012 fputs ("+", file);
2013 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2014 }
2015 else
633e4eb4 2016 {
f42f5a1b
BW
2017 output_addr_const (file, x);
2018 fputs (letter == 't' ? "@h" : "@l", file);
03984308
BW
2019 }
2020 break;
2021
2022 default:
f42f5a1b
BW
2023 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2024 fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2025 else if (GET_CODE (x) == MEM)
2026 output_address (XEXP (x, 0));
2027 else if (GET_CODE (x) == CONST_INT)
2028 fprintf (file, "%ld", INTVAL (x));
2029 else
2030 output_addr_const (file, x);
03984308
BW
2031 }
2032}
2033
2034
2035/* A C compound statement to output to stdio stream STREAM the
2036 assembler syntax for an instruction operand that is a memory
fb49053f 2037 reference whose address is ADDR. ADDR is an RTL expression. */
03984308
BW
2038
2039void
ffbc8796 2040print_operand_address (FILE *file, rtx addr)
03984308
BW
2041{
2042 if (!addr)
2043 error ("PRINT_OPERAND_ADDRESS, null pointer");
2044
2045 switch (GET_CODE (addr))
2046 {
2047 default:
2048 fatal_insn ("invalid address", addr);
2049 break;
2050
2051 case REG:
2052 fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2053 break;
2054
2055 case PLUS:
2056 {
2057 rtx reg = (rtx)0;
2058 rtx offset = (rtx)0;
2059 rtx arg0 = XEXP (addr, 0);
2060 rtx arg1 = XEXP (addr, 1);
2061
2062 if (GET_CODE (arg0) == REG)
2063 {
2064 reg = arg0;
2065 offset = arg1;
2066 }
2067 else if (GET_CODE (arg1) == REG)
2068 {
2069 reg = arg1;
2070 offset = arg0;
2071 }
2072 else
2073 fatal_insn ("no register in address", addr);
2074
2075 if (CONSTANT_P (offset))
2076 {
2077 fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2078 output_addr_const (file, offset);
2079 }
2080 else
2081 fatal_insn ("address offset not a constant", addr);
2082 }
2083 break;
2084
2085 case LABEL_REF:
2086 case SYMBOL_REF:
2087 case CONST_INT:
2088 case CONST:
2089 output_addr_const (file, addr);
2090 break;
2091 }
2092}
2093
2094
03984308 2095void
ffbc8796 2096xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno)
03984308
BW
2097{
2098 long value_long[2];
b216cd4a 2099 REAL_VALUE_TYPE r;
03984308
BW
2100 int size;
2101
2102 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2103
2104 switch (GET_MODE_CLASS (mode))
2105 {
2106 case MODE_FLOAT:
2107 if (GET_CODE (x) != CONST_DOUBLE)
2108 abort ();
2109
b216cd4a 2110 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
03984308
BW
2111 switch (mode)
2112 {
2113 case SFmode:
b216cd4a
ZW
2114 REAL_VALUE_TO_TARGET_SINGLE (r, value_long[0]);
2115 fprintf (file, "0x%08lx\n", value_long[0]);
03984308
BW
2116 break;
2117
2118 case DFmode:
b216cd4a
ZW
2119 REAL_VALUE_TO_TARGET_DOUBLE (r, value_long);
2120 fprintf (file, "0x%08lx, 0x%08lx\n",
2121 value_long[0], value_long[1]);
03984308
BW
2122 break;
2123
2124 default:
2125 abort ();
2126 }
2127
2128 break;
2129
2130 case MODE_INT:
2131 case MODE_PARTIAL_INT:
2132 size = GET_MODE_SIZE (mode);
2133 if (size == 4)
2134 {
2135 output_addr_const (file, x);
2136 fputs ("\n", file);
2137 }
2138 else if (size == 8)
2139 {
2140 output_addr_const (file, operand_subword (x, 0, 0, DImode));
2141 fputs (", ", file);
2142 output_addr_const (file, operand_subword (x, 1, 0, DImode));
2143 fputs ("\n", file);
2144 }
2145 else
2146 abort ();
2147 break;
2148
2149 default:
2150 abort ();
2151 }
2152}
2153
2154
2155/* Return the bytes needed to compute the frame pointer from the current
638db43e 2156 stack pointer. */
03984308
BW
2157
2158#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2159#define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2160
2161long
ffbc8796 2162compute_frame_size (int size)
03984308 2163{
ffbc8796 2164 /* Add space for the incoming static chain value. */
6de9cd9a 2165 if (cfun->static_chain_decl != NULL)
03984308
BW
2166 size += (1 * UNITS_PER_WORD);
2167
2168 xtensa_current_frame_size =
2169 XTENSA_STACK_ALIGN (size
2170 + current_function_outgoing_args_size
2171 + (WINDOW_SIZE * UNITS_PER_WORD));
2172 return xtensa_current_frame_size;
2173}
2174
2175
2176int
ffbc8796 2177xtensa_frame_pointer_required (void)
03984308
BW
2178{
2179 /* The code to expand builtin_frame_addr and builtin_return_addr
2180 currently uses the hard_frame_pointer instead of frame_pointer.
2181 This seems wrong but maybe it's necessary for other architectures.
638db43e 2182 This function is derived from the i386 code. */
03984308
BW
2183
2184 if (cfun->machine->accesses_prev_frame)
2185 return 1;
2186
2187 return 0;
2188}
2189
2190
f42f5a1b 2191void
ffbc8796 2192xtensa_expand_prologue (void)
f42f5a1b
BW
2193{
2194 HOST_WIDE_INT total_size;
2195 rtx size_rtx;
18dbd950 2196
f42f5a1b
BW
2197 total_size = compute_frame_size (get_frame_size ());
2198 size_rtx = GEN_INT (total_size);
18dbd950 2199
f42f5a1b
BW
2200 if (total_size < (1 << (12+3)))
2201 emit_insn (gen_entry (size_rtx, size_rtx));
03984308
BW
2202 else
2203 {
f42f5a1b
BW
2204 /* Use a8 as a temporary since a0-a7 may be live. */
2205 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2206 emit_insn (gen_entry (size_rtx, GEN_INT (MIN_FRAME_SIZE)));
2207 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2208 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2209 emit_move_insn (stack_pointer_rtx, tmp_reg);
03984308
BW
2210 }
2211
f42f5a1b 2212 if (frame_pointer_needed)
03984308 2213 {
997b8b4d 2214 if (cfun->machine->set_frame_ptr_insn)
03984308 2215 {
997b8b4d 2216 rtx first, insn;
03984308 2217
997b8b4d
BW
2218 push_topmost_sequence ();
2219 first = get_insns ();
2220 pop_topmost_sequence ();
03984308 2221
f42f5a1b
BW
2222 /* For all instructions prior to set_frame_ptr_insn, replace
2223 hard_frame_pointer references with stack_pointer. */
2224 for (insn = first;
997b8b4d 2225 insn != cfun->machine->set_frame_ptr_insn;
f42f5a1b
BW
2226 insn = NEXT_INSN (insn))
2227 {
2228 if (INSN_P (insn))
2229 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2230 hard_frame_pointer_rtx,
2231 stack_pointer_rtx);
2232 }
2233 }
2234 else
2235 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
03984308
BW
2236 }
2237}
2238
2239
f42f5a1b 2240/* Clear variables at function end. */
03984308
BW
2241
2242void
ffbc8796
BW
2243xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
2244 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
03984308 2245{
03984308
BW
2246 xtensa_current_frame_size = 0;
2247}
2248
2249
0c14a54d 2250rtx
ffbc8796 2251xtensa_return_addr (int count, rtx frame)
0c14a54d
BW
2252{
2253 rtx result, retaddr;
2254
2255 if (count == -1)
f42f5a1b 2256 retaddr = gen_rtx_REG (Pmode, A0_REG);
0c14a54d
BW
2257 else
2258 {
2259 rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
2260 addr = memory_address (Pmode, addr);
2261 retaddr = gen_reg_rtx (Pmode);
2262 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
2263 }
2264
2265 /* The 2 most-significant bits of the return address on Xtensa hold
2266 the register window size. To get the real return address, these
2267 bits must be replaced with the high bits from the current PC. */
2268
2269 result = gen_reg_rtx (Pmode);
2270 emit_insn (gen_fix_return_addr (result, retaddr));
2271 return result;
2272}
2273
2274
03984308 2275/* Create the va_list data type.
822e895c
BW
2276
2277 This structure is set up by __builtin_saveregs. The __va_reg field
2278 points to a stack-allocated region holding the contents of the
2279 incoming argument registers. The __va_ndx field is an index
2280 initialized to the position of the first unnamed (variable)
2281 argument. This same index is also used to address the arguments
2282 passed in memory. Thus, the __va_stk field is initialized to point
2283 to the position of the first argument in memory offset to account
2284 for the arguments passed in registers and to account for the size
2285 of the argument registers not being 16-byte aligned. E.G., there
2286 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2287 for the first stack argument to have the maximal alignment of 16
2288 bytes, so we offset the __va_stk address by 32 bytes so that
2289 __va_stk[32] references the first argument on the stack. */
03984308 2290
c35d187f
RH
2291static tree
2292xtensa_build_builtin_va_list (void)
03984308 2293{
540eaea8 2294 tree f_stk, f_reg, f_ndx, record, type_decl;
03984308 2295
540eaea8
BW
2296 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2297 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
03984308
BW
2298
2299 f_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"),
2300 ptr_type_node);
2301 f_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"),
2302 ptr_type_node);
2303 f_ndx = build_decl (FIELD_DECL, get_identifier ("__va_ndx"),
2304 integer_type_node);
2305
2306 DECL_FIELD_CONTEXT (f_stk) = record;
2307 DECL_FIELD_CONTEXT (f_reg) = record;
2308 DECL_FIELD_CONTEXT (f_ndx) = record;
2309
540eaea8
BW
2310 TREE_CHAIN (record) = type_decl;
2311 TYPE_NAME (record) = type_decl;
03984308
BW
2312 TYPE_FIELDS (record) = f_stk;
2313 TREE_CHAIN (f_stk) = f_reg;
2314 TREE_CHAIN (f_reg) = f_ndx;
2315
2316 layout_type (record);
2317 return record;
2318}
2319
2320
2321/* Save the incoming argument registers on the stack. Returns the
638db43e 2322 address of the saved registers. */
03984308 2323
4c45af42 2324static rtx
ffbc8796 2325xtensa_builtin_saveregs (void)
03984308
BW
2326{
2327 rtx gp_regs, dest;
79e9ebdc 2328 int arg_words = current_function_args_info.arg_words;
03984308 2329 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
03984308 2330
997b8b4d 2331 if (gp_left <= 0)
03984308
BW
2332 return const0_rtx;
2333
3bbc2af6 2334 /* Allocate the general-purpose register space. */
03984308
BW
2335 gp_regs = assign_stack_local
2336 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
540eaea8 2337 set_mem_alias_set (gp_regs, get_varargs_alias_set ());
03984308
BW
2338
2339 /* Now store the incoming registers. */
2340 dest = change_address (gp_regs, SImode,
2341 plus_constant (XEXP (gp_regs, 0),
2342 arg_words * UNITS_PER_WORD));
997b8b4d
BW
2343 cfun->machine->need_a7_copy = true;
2344 cfun->machine->vararg_a7 = true;
2345 move_block_from_reg (GP_ARG_FIRST + arg_words, dest, gp_left);
03984308
BW
2346
2347 return XEXP (gp_regs, 0);
2348}
2349
2350
2351/* Implement `va_start' for varargs and stdarg. We look at the
638db43e 2352 current function to fill in an initial va_list. */
03984308
BW
2353
2354void
ffbc8796 2355xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
03984308
BW
2356{
2357 tree f_stk, stk;
2358 tree f_reg, reg;
2359 tree f_ndx, ndx;
2360 tree t, u;
2361 int arg_words;
2362
2363 arg_words = current_function_args_info.arg_words;
2364
2365 f_stk = TYPE_FIELDS (va_list_type_node);
2366 f_reg = TREE_CHAIN (f_stk);
2367 f_ndx = TREE_CHAIN (f_reg);
2368
44de5aeb
RK
2369 stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2370 reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
2371 ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
03984308
BW
2372
2373 /* Call __builtin_saveregs; save the result in __va_reg */
03984308
BW
2374 u = make_tree (ptr_type_node, expand_builtin_saveregs ());
2375 t = build (MODIFY_EXPR, ptr_type_node, reg, u);
2376 TREE_SIDE_EFFECTS (t) = 1;
2377 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2378
822e895c 2379 /* Set the __va_stk member to ($arg_ptr - 32). */
03984308 2380 u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
4a90aeeb 2381 u = fold (build (PLUS_EXPR, ptr_type_node, u,
7d60be94 2382 build_int_cst (NULL_TREE, -32)));
03984308
BW
2383 t = build (MODIFY_EXPR, ptr_type_node, stk, u);
2384 TREE_SIDE_EFFECTS (t) = 1;
2385 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2386
822e895c
BW
2387 /* Set the __va_ndx member. If the first variable argument is on
2388 the stack, adjust __va_ndx by 2 words to account for the extra
2389 alignment offset for __va_stk. */
2390 if (arg_words >= MAX_ARGS_IN_REGISTERS)
2391 arg_words += 2;
7d60be94 2392 u = build_int_cst (NULL_TREE, arg_words * UNITS_PER_WORD);
03984308
BW
2393 t = build (MODIFY_EXPR, integer_type_node, ndx, u);
2394 TREE_SIDE_EFFECTS (t) = 1;
2395 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2396}
2397
2398
2399/* Implement `va_arg'. */
2400
85d53c1d
RH
2401static tree
2402xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
2403 tree *post_p ATTRIBUTE_UNUSED)
03984308
BW
2404{
2405 tree f_stk, stk;
2406 tree f_reg, reg;
2407 tree f_ndx, ndx;
85d53c1d
RH
2408 tree type_size, array, orig_ndx, addr, size, va_size, t;
2409 tree lab_false, lab_over, lab_false2;
08b0dc1b
RH
2410 bool indirect;
2411
2412 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
2413 if (indirect)
2414 type = build_pointer_type (type);
03984308 2415
3712281f
BW
2416 /* Handle complex values as separate real and imaginary parts. */
2417 if (TREE_CODE (type) == COMPLEX_TYPE)
2418 {
85d53c1d 2419 tree real_part, imag_part;
3712281f 2420
85d53c1d
RH
2421 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2422 pre_p, NULL);
2423 real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
3712281f 2424
85d53c1d
RH
2425 imag_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
2426 pre_p, NULL);
2427 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
3712281f 2428
85d53c1d 2429 return build (COMPLEX_EXPR, type, real_part, imag_part);
3712281f
BW
2430 }
2431
03984308
BW
2432 f_stk = TYPE_FIELDS (va_list_type_node);
2433 f_reg = TREE_CHAIN (f_stk);
2434 f_ndx = TREE_CHAIN (f_reg);
2435
44de5aeb
RK
2436 stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
2437 reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
2438 ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
03984308 2439
85d53c1d
RH
2440 type_size = size_in_bytes (type);
2441 va_size = round_up (type_size, UNITS_PER_WORD);
2442 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
8be56275 2443
03984308 2444
822e895c 2445 /* First align __va_ndx if necessary for this arg:
03984308 2446
85d53c1d 2447 orig_ndx = (AP).__va_ndx;
822e895c 2448 if (__alignof__ (TYPE) > 4 )
85d53c1d 2449 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
822e895c 2450 & -__alignof__ (TYPE)); */
03984308 2451
85d53c1d
RH
2452 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
2453
03984308
BW
2454 if (TYPE_ALIGN (type) > BITS_PER_WORD)
2455 {
822e895c 2456 int align = TYPE_ALIGN (type) / BITS_PER_UNIT;
85d53c1d
RH
2457
2458 t = build (PLUS_EXPR, integer_type_node, orig_ndx,
7d60be94 2459 build_int_cst (NULL_TREE, align - 1));
85d53c1d 2460 t = build (BIT_AND_EXPR, integer_type_node, t,
7d60be94 2461 build_int_cst (NULL_TREE, -align));
85d53c1d
RH
2462 t = build (MODIFY_EXPR, integer_type_node, orig_ndx, t);
2463 gimplify_and_add (t, pre_p);
03984308
BW
2464 }
2465
2466
2467 /* Increment __va_ndx to point past the argument:
2468
85d53c1d 2469 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
03984308 2470
85d53c1d
RH
2471 t = fold_convert (integer_type_node, va_size);
2472 t = build (PLUS_EXPR, integer_type_node, orig_ndx, t);
2473 t = build (MODIFY_EXPR, integer_type_node, ndx, t);
2474 gimplify_and_add (t, pre_p);
03984308
BW
2475
2476
2477 /* Check if the argument is in registers:
2478
bcf88f9b 2479 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
fe984136 2480 && !must_pass_in_stack (type))
ffbc8796 2481 __array = (AP).__va_reg; */
03984308 2482
85d53c1d 2483 array = create_tmp_var (ptr_type_node, NULL);
03984308 2484
85d53c1d 2485 lab_over = NULL;
fe984136 2486 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
bcf88f9b 2487 {
85d53c1d
RH
2488 lab_false = create_artificial_label ();
2489 lab_over = create_artificial_label ();
2490
7d60be94 2491 t = build_int_cst (NULL_TREE, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD);
85d53c1d
RH
2492 t = build (GT_EXPR, boolean_type_node, ndx, t);
2493 t = build (COND_EXPR, void_type_node, t,
2494 build (GOTO_EXPR, void_type_node, lab_false),
2495 NULL);
2496 gimplify_and_add (t, pre_p);
2497
2498 t = build (MODIFY_EXPR, void_type_node, array, reg);
2499 gimplify_and_add (t, pre_p);
2500
2501 t = build (GOTO_EXPR, void_type_node, lab_over);
2502 gimplify_and_add (t, pre_p);
2503
2504 t = build (LABEL_EXPR, void_type_node, lab_false);
2505 gimplify_and_add (t, pre_p);
bcf88f9b 2506 }
03984308 2507
85d53c1d 2508
03984308
BW
2509 /* ...otherwise, the argument is on the stack (never split between
2510 registers and the stack -- change __va_ndx if necessary):
2511
2512 else
2513 {
822e895c
BW
2514 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2515 (AP).__va_ndx = 32 + __va_size (TYPE);
03984308 2516 __array = (AP).__va_stk;
ffbc8796 2517 } */
03984308 2518
85d53c1d 2519 lab_false2 = create_artificial_label ();
03984308 2520
7d60be94 2521 t = build_int_cst (NULL_TREE, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD);
85d53c1d
RH
2522 t = build (GT_EXPR, boolean_type_node, orig_ndx, t);
2523 t = build (COND_EXPR, void_type_node, t,
2524 build (GOTO_EXPR, void_type_node, lab_false2),
2525 NULL);
2526 gimplify_and_add (t, pre_p);
03984308 2527
85d53c1d
RH
2528 t = size_binop (PLUS_EXPR, va_size, size_int (32));
2529 t = fold_convert (integer_type_node, t);
2530 t = build (MODIFY_EXPR, integer_type_node, ndx, t);
2531 gimplify_and_add (t, pre_p);
03984308 2532
85d53c1d
RH
2533 t = build (LABEL_EXPR, void_type_node, lab_false2);
2534 gimplify_and_add (t, pre_p);
03984308 2535
85d53c1d
RH
2536 t = build (MODIFY_EXPR, void_type_node, array, stk);
2537 gimplify_and_add (t, pre_p);
2538
2539 if (lab_over)
2540 {
2541 t = build (LABEL_EXPR, void_type_node, lab_over);
2542 gimplify_and_add (t, pre_p);
2543 }
8be56275 2544
03984308
BW
2545
2546 /* Given the base array pointer (__array) and index to the subsequent
2547 argument (__va_ndx), find the address:
2548
8be56275
BW
2549 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2550 ? sizeof (TYPE)
2551 : __va_size (TYPE))
03984308
BW
2552
2553 The results are endian-dependent because values smaller than one word
ffbc8796 2554 are aligned differently. */
03984308 2555
633e4eb4 2556
85d91d5b 2557 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
8be56275 2558 {
85d53c1d
RH
2559 t = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
2560 t = fold (build (GE_EXPR, boolean_type_node, type_size, t));
e231737a 2561 t = fold (build (COND_EXPR, sizetype, t, va_size, type_size));
85d53c1d 2562 size = t;
8be56275 2563 }
85d53c1d
RH
2564 else
2565 size = va_size;
2566
2567 t = fold_convert (ptr_type_node, ndx);
2568 addr = build (PLUS_EXPR, ptr_type_node, array, t);
2569 t = fold_convert (ptr_type_node, size);
2570 addr = build (MINUS_EXPR, ptr_type_node, addr, t);
03984308 2571
85d53c1d 2572 addr = fold_convert (build_pointer_type (type), addr);
08b0dc1b
RH
2573 if (indirect)
2574 addr = build_fold_indirect_ref (addr);
85d53c1d 2575 return build_fold_indirect_ref (addr);
03984308
BW
2576}
2577
2578
a8cacfd2 2579enum reg_class
ffbc8796 2580xtensa_preferred_reload_class (rtx x, enum reg_class class, int isoutput)
a8cacfd2 2581{
89f6025d 2582 if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
a8cacfd2
BW
2583 return NO_REGS;
2584
89f6025d
BW
2585 /* Don't use the stack pointer or hard frame pointer for reloads!
2586 The hard frame pointer would normally be OK except that it may
2587 briefly hold an incoming argument in the prologue, and reload
2588 won't know that it is live because the hard frame pointer is
2589 treated specially. */
2590
2591 if (class == AR_REGS || class == GR_REGS)
2592 return RL_REGS;
a8cacfd2
BW
2593
2594 return class;
2595}
2596
2597
03984308 2598enum reg_class
ffbc8796
BW
2599xtensa_secondary_reload_class (enum reg_class class,
2600 enum machine_mode mode ATTRIBUTE_UNUSED,
2601 rtx x, int isoutput)
03984308
BW
2602{
2603 int regno;
2604
2605 if (GET_CODE (x) == SIGN_EXTEND)
2606 x = XEXP (x, 0);
2607 regno = xt_true_regnum (x);
2608
2609 if (!isoutput)
2610 {
2611 if (class == FP_REGS && constantpool_mem_p (x))
89f6025d 2612 return RL_REGS;
03984308
BW
2613 }
2614
2615 if (ACC_REG_P (regno))
89f6025d 2616 return ((class == GR_REGS || class == RL_REGS) ? NO_REGS : RL_REGS);
03984308 2617 if (class == ACC_REG)
89f6025d 2618 return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
03984308
BW
2619
2620 return NO_REGS;
2621}
2622
2623
2624void
ffbc8796 2625order_regs_for_local_alloc (void)
03984308
BW
2626{
2627 if (!leaf_function_p ())
2628 {
2629 memcpy (reg_alloc_order, reg_nonleaf_alloc_order,
2630 FIRST_PSEUDO_REGISTER * sizeof (int));
2631 }
2632 else
2633 {
2634 int i, num_arg_regs;
2635 int nxt = 0;
2636
3bbc2af6
KH
2637 /* Use the AR registers in increasing order (skipping a0 and a1)
2638 but save the incoming argument registers for a last resort. */
03984308
BW
2639 num_arg_regs = current_function_args_info.arg_words;
2640 if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
2641 num_arg_regs = MAX_ARGS_IN_REGISTERS;
2642 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
2643 reg_alloc_order[nxt++] = i + num_arg_regs;
2644 for (i = 0; i < num_arg_regs; i++)
2645 reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
2646
3bbc2af6 2647 /* List the coprocessor registers in order. */
985d0d50
BW
2648 for (i = 0; i < BR_REG_NUM; i++)
2649 reg_alloc_order[nxt++] = BR_REG_FIRST + i;
2650
3bbc2af6 2651 /* List the FP registers in order for now. */
03984308
BW
2652 for (i = 0; i < 16; i++)
2653 reg_alloc_order[nxt++] = FP_REG_FIRST + i;
2654
638db43e 2655 /* GCC requires that we list *all* the registers.... */
03984308
BW
2656 reg_alloc_order[nxt++] = 0; /* a0 = return address */
2657 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */
2658 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */
2659 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */
2660
03984308
BW
2661 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */
2662 }
2663}
2664
2665
01abf342
BW
2666/* Some Xtensa targets support multiple bss sections. If the section
2667 name ends with ".bss", add SECTION_BSS to the flags. */
2668
2669static unsigned int
ffbc8796 2670xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
01abf342
BW
2671{
2672 unsigned int flags = default_section_type_flags (decl, name, reloc);
2673 const char *suffix;
2674
2675 suffix = strrchr (name, '.');
2676 if (suffix && strcmp (suffix, ".bss") == 0)
2677 {
2678 if (!decl || (TREE_CODE (decl) == VAR_DECL
2679 && DECL_INITIAL (decl) == NULL_TREE))
2680 flags |= SECTION_BSS; /* @nobits */
2681 else
2682 warning ("only uninitialized variables can be placed in a "
2683 ".bss section");
2684 }
2685
2686 return flags;
2687}
2688
2689
b64a1b53
RH
2690/* The literal pool stays with the function. */
2691
2692static void
ffbc8796
BW
2693xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
2694 rtx x ATTRIBUTE_UNUSED,
2695 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
b64a1b53
RH
2696{
2697 function_section (current_function_decl);
2698}
fb49053f 2699
ffbc8796 2700
3c50106f
RH
2701/* Compute a (partial) cost for rtx X. Return true if the complete
2702 cost has been computed, and false if subexpressions should be
2703 scanned. In either case, *TOTAL contains the cost result. */
2704
2705static bool
ffbc8796 2706xtensa_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f
RH
2707{
2708 switch (code)
2709 {
2710 case CONST_INT:
2711 switch (outer_code)
2712 {
2713 case SET:
2714 if (xtensa_simm12b (INTVAL (x)))
2715 {
2716 *total = 4;
2717 return true;
2718 }
2719 break;
2720 case PLUS:
2721 if (xtensa_simm8 (INTVAL (x))
2722 || xtensa_simm8x256 (INTVAL (x)))
2723 {
2724 *total = 0;
2725 return true;
2726 }
2727 break;
2728 case AND:
2729 if (xtensa_mask_immediate (INTVAL (x)))
2730 {
2731 *total = 0;
2732 return true;
2733 }
2734 break;
2735 case COMPARE:
2736 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
2737 {
2738 *total = 0;
2739 return true;
2740 }
2741 break;
2742 case ASHIFT:
2743 case ASHIFTRT:
2744 case LSHIFTRT:
2745 case ROTATE:
2746 case ROTATERT:
3bbc2af6 2747 /* No way to tell if X is the 2nd operand so be conservative. */
3c50106f
RH
2748 default: break;
2749 }
2750 if (xtensa_simm12b (INTVAL (x)))
2751 *total = 5;
f42f5a1b
BW
2752 else if (TARGET_CONST16)
2753 *total = COSTS_N_INSNS (2);
3c50106f
RH
2754 else
2755 *total = 6;
2756 return true;
2757
2758 case CONST:
2759 case LABEL_REF:
2760 case SYMBOL_REF:
f42f5a1b
BW
2761 if (TARGET_CONST16)
2762 *total = COSTS_N_INSNS (2);
2763 else
2764 *total = 5;
3c50106f
RH
2765 return true;
2766
2767 case CONST_DOUBLE:
f42f5a1b
BW
2768 if (TARGET_CONST16)
2769 *total = COSTS_N_INSNS (4);
2770 else
2771 *total = 7;
3c50106f
RH
2772 return true;
2773
2774 case MEM:
2775 {
2776 int num_words =
2777 (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ? 2 : 1;
2778
2779 if (memory_address_p (GET_MODE (x), XEXP ((x), 0)))
2780 *total = COSTS_N_INSNS (num_words);
2781 else
2782 *total = COSTS_N_INSNS (2*num_words);
2783 return true;
2784 }
2785
2786 case FFS:
2787 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
2788 return true;
2789
2790 case NOT:
2791 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 3 : 2);
2792 return true;
2793
2794 case AND:
2795 case IOR:
2796 case XOR:
2797 if (GET_MODE (x) == DImode)
2798 *total = COSTS_N_INSNS (2);
2799 else
2800 *total = COSTS_N_INSNS (1);
2801 return true;
2802
2803 case ASHIFT:
2804 case ASHIFTRT:
2805 case LSHIFTRT:
2806 if (GET_MODE (x) == DImode)
2807 *total = COSTS_N_INSNS (50);
2808 else
2809 *total = COSTS_N_INSNS (1);
2810 return true;
2811
2812 case ABS:
2813 {
2814 enum machine_mode xmode = GET_MODE (x);
2815 if (xmode == SFmode)
2816 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
2817 else if (xmode == DFmode)
2818 *total = COSTS_N_INSNS (50);
2819 else
2820 *total = COSTS_N_INSNS (4);
2821 return true;
2822 }
2823
2824 case PLUS:
2825 case MINUS:
2826 {
2827 enum machine_mode xmode = GET_MODE (x);
2828 if (xmode == SFmode)
2829 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
2830 else if (xmode == DFmode || xmode == DImode)
2831 *total = COSTS_N_INSNS (50);
2832 else
2833 *total = COSTS_N_INSNS (1);
2834 return true;
2835 }
2836
2837 case NEG:
2838 *total = COSTS_N_INSNS ((GET_MODE (x) == DImode) ? 4 : 2);
2839 return true;
2840
2841 case MULT:
2842 {
2843 enum machine_mode xmode = GET_MODE (x);
2844 if (xmode == SFmode)
2845 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
2846 else if (xmode == DFmode || xmode == DImode)
2847 *total = COSTS_N_INSNS (50);
2848 else if (TARGET_MUL32)
2849 *total = COSTS_N_INSNS (4);
2850 else if (TARGET_MAC16)
2851 *total = COSTS_N_INSNS (16);
2852 else if (TARGET_MUL16)
2853 *total = COSTS_N_INSNS (12);
2854 else
2855 *total = COSTS_N_INSNS (50);
2856 return true;
2857 }
2858
2859 case DIV:
2860 case MOD:
2861 {
2862 enum machine_mode xmode = GET_MODE (x);
2863 if (xmode == SFmode)
2864 {
2865 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
2866 return true;
2867 }
2868 else if (xmode == DFmode)
2869 {
2870 *total = COSTS_N_INSNS (50);
2871 return true;
2872 }
2873 }
3bbc2af6 2874 /* Fall through. */
3c50106f
RH
2875
2876 case UDIV:
2877 case UMOD:
2878 {
2879 enum machine_mode xmode = GET_MODE (x);
2880 if (xmode == DImode)
2881 *total = COSTS_N_INSNS (50);
2882 else if (TARGET_DIV32)
2883 *total = COSTS_N_INSNS (32);
2884 else
2885 *total = COSTS_N_INSNS (50);
2886 return true;
2887 }
2888
2889 case SQRT:
2890 if (GET_MODE (x) == SFmode)
2891 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
2892 else
2893 *total = COSTS_N_INSNS (50);
2894 return true;
2895
2896 case SMIN:
2897 case UMIN:
2898 case SMAX:
2899 case UMAX:
2900 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
2901 return true;
2902
2903 case SIGN_EXTRACT:
2904 case SIGN_EXTEND:
2905 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
2906 return true;
2907
2908 case ZERO_EXTRACT:
2909 case ZERO_EXTEND:
2910 *total = COSTS_N_INSNS (1);
2911 return true;
2912
2913 default:
2914 return false;
2915 }
2916}
2917
bd5bd7ac
KH
2918/* Worker function for TARGET_RETURN_IN_MEMORY. */
2919
4c45af42
KH
2920static bool
2921xtensa_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
2922{
2923 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
2924 > 4 * UNITS_PER_WORD);
2925}
2926
e2500fed 2927#include "gt-xtensa.h"