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