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