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