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