OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [iq2000/] [iq2000.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* Subroutines used for code generation on Vitesse IQ2000 processors
2
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "tree.h"
26
#include "rtl.h"
27
#include "regs.h"
28
#include "hard-reg-set.h"
29
#include "insn-config.h"
30
#include "conditions.h"
31
#include "output.h"
32
#include "insn-attr.h"
33
#include "flags.h"
34
#include "function.h"
35
#include "expr.h"
36
#include "optabs.h"
37
#include "libfuncs.h"
38
#include "recog.h"
39
#include "diagnostic-core.h"
40
#include "reload.h"
41
#include "ggc.h"
42
#include "tm_p.h"
43
#include "debug.h"
44
#include "target.h"
45
#include "target-def.h"
46
#include "langhooks.h"
47
#include "df.h"
48
 
49
/* Enumeration for all of the relational tests, so that we can build
50
   arrays indexed by the test type, and not worry about the order
51
   of EQ, NE, etc.  */
52
 
53
enum internal_test
54
  {
55
    ITEST_EQ,
56
    ITEST_NE,
57
    ITEST_GT,
58
    ITEST_GE,
59
    ITEST_LT,
60
    ITEST_LE,
61
    ITEST_GTU,
62
    ITEST_GEU,
63
    ITEST_LTU,
64
    ITEST_LEU,
65
    ITEST_MAX
66
  };
67
 
68
struct constant;
69
 
70
 
71
/* Structure to be filled in by compute_frame_size with register
72
   save masks, and offsets for the current function.  */
73
 
74
struct iq2000_frame_info
75
{
76
  long total_size;              /* # bytes that the entire frame takes up.  */
77
  long var_size;                /* # bytes that variables take up.  */
78
  long args_size;               /* # bytes that outgoing arguments take up.  */
79
  long extra_size;              /* # bytes of extra gunk.  */
80
  int  gp_reg_size;             /* # bytes needed to store gp regs.  */
81
  int  fp_reg_size;             /* # bytes needed to store fp regs.  */
82
  long mask;                    /* Mask of saved gp registers.  */
83
  long gp_save_offset;          /* Offset from vfp to store gp registers.  */
84
  long fp_save_offset;          /* Offset from vfp to store fp registers.  */
85
  long gp_sp_offset;            /* Offset from new sp to store gp registers.  */
86
  long fp_sp_offset;            /* Offset from new sp to store fp registers.  */
87
  int  initialized;             /* != 0 if frame size already calculated.  */
88
  int  num_gp;                  /* Number of gp registers saved.  */
89
} iq2000_frame_info;
90
 
91
struct GTY(()) machine_function
92
{
93
  /* Current frame information, calculated by compute_frame_size.  */
94
  long total_size;              /* # bytes that the entire frame takes up.  */
95
  long var_size;                /* # bytes that variables take up.  */
96
  long args_size;               /* # bytes that outgoing arguments take up.  */
97
  long extra_size;              /* # bytes of extra gunk.  */
98
  int  gp_reg_size;             /* # bytes needed to store gp regs.  */
99
  int  fp_reg_size;             /* # bytes needed to store fp regs.  */
100
  long mask;                    /* Mask of saved gp registers.  */
101
  long gp_save_offset;          /* Offset from vfp to store gp registers.  */
102
  long fp_save_offset;          /* Offset from vfp to store fp registers.  */
103
  long gp_sp_offset;            /* Offset from new sp to store gp registers.  */
104
  long fp_sp_offset;            /* Offset from new sp to store fp registers.  */
105
  int  initialized;             /* != 0 if frame size already calculated.  */
106
  int  num_gp;                  /* Number of gp registers saved.  */
107
};
108
 
109
/* Global variables for machine-dependent things.  */
110
 
111
/* List of all IQ2000 punctuation characters used by iq2000_print_operand.  */
112
static char iq2000_print_operand_punct[256];
113
 
114
/* Which instruction set architecture to use.  */
115
int iq2000_isa;
116
 
117
/* Local variables.  */
118
 
119
/* The next branch instruction is a branch likely, not branch normal.  */
120
static int iq2000_branch_likely;
121
 
122
/* Count of delay slots and how many are filled.  */
123
static int dslots_load_total;
124
static int dslots_load_filled;
125
static int dslots_jump_total;
126
 
127
/* # of nops needed by previous insn.  */
128
static int dslots_number_nops;
129
 
130
/* Number of 1/2/3 word references to data items (i.e., not jal's).  */
131
static int num_refs[3];
132
 
133
/* Registers to check for load delay.  */
134
static rtx iq2000_load_reg;
135
static rtx iq2000_load_reg2;
136
static rtx iq2000_load_reg3;
137
static rtx iq2000_load_reg4;
138
 
139
/* Mode used for saving/restoring general purpose registers.  */
140
static enum machine_mode gpr_mode;
141
 
142
 
143
/* Initialize the GCC target structure.  */
144
static struct machine_function* iq2000_init_machine_status (void);
145
static void iq2000_option_override    (void);
146
static section *iq2000_select_rtx_section (enum machine_mode, rtx,
147
                                           unsigned HOST_WIDE_INT);
148
static void iq2000_init_builtins      (void);
149
static rtx  iq2000_expand_builtin     (tree, rtx, rtx, enum machine_mode, int);
150
static bool iq2000_return_in_memory   (const_tree, const_tree);
151
static void iq2000_setup_incoming_varargs (cumulative_args_t,
152
                                           enum machine_mode, tree, int *,
153
                                           int);
154
static bool iq2000_rtx_costs          (rtx, int, int, int, int *, bool);
155
static int  iq2000_address_cost       (rtx, bool);
156
static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
157
static rtx  iq2000_legitimize_address (rtx, rtx, enum machine_mode);
158
static bool iq2000_pass_by_reference  (cumulative_args_t, enum machine_mode,
159
                                       const_tree, bool);
160
static int  iq2000_arg_partial_bytes  (cumulative_args_t, enum machine_mode,
161
                                       tree, bool);
162
static rtx iq2000_function_arg        (cumulative_args_t,
163
                                       enum machine_mode, const_tree, bool);
164
static void iq2000_function_arg_advance (cumulative_args_t,
165
                                         enum machine_mode, const_tree, bool);
166
static unsigned int iq2000_function_arg_boundary (enum machine_mode,
167
                                                  const_tree);
168
static void iq2000_va_start           (tree, rtx);
169
static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
170
static bool iq2000_can_eliminate      (const int, const int);
171
static void iq2000_asm_trampoline_template (FILE *);
172
static void iq2000_trampoline_init    (rtx, tree, rtx);
173
static rtx iq2000_function_value      (const_tree, const_tree, bool);
174
static rtx iq2000_libcall_value       (enum machine_mode, const_rtx);
175
static void iq2000_print_operand      (FILE *, rtx, int);
176
static void iq2000_print_operand_address (FILE *, rtx);
177
static bool iq2000_print_operand_punct_valid_p (unsigned char code);
178
 
179
#undef  TARGET_INIT_BUILTINS
180
#define TARGET_INIT_BUILTINS            iq2000_init_builtins
181
#undef  TARGET_EXPAND_BUILTIN
182
#define TARGET_EXPAND_BUILTIN           iq2000_expand_builtin
183
#undef  TARGET_ASM_SELECT_RTX_SECTION
184
#define TARGET_ASM_SELECT_RTX_SECTION   iq2000_select_rtx_section
185
#undef  TARGET_OPTION_OVERRIDE
186
#define TARGET_OPTION_OVERRIDE          iq2000_option_override
187
#undef  TARGET_RTX_COSTS
188
#define TARGET_RTX_COSTS                iq2000_rtx_costs
189
#undef  TARGET_ADDRESS_COST
190
#define TARGET_ADDRESS_COST             iq2000_address_cost
191
#undef  TARGET_ASM_SELECT_SECTION
192
#define TARGET_ASM_SELECT_SECTION       iq2000_select_section
193
 
194
#undef TARGET_LEGITIMIZE_ADDRESS
195
#define TARGET_LEGITIMIZE_ADDRESS       iq2000_legitimize_address
196
 
197
/* The assembler supports switchable .bss sections, but
198
   iq2000_select_section doesn't yet make use of them.  */
199
#undef  TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
200
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
201
 
202
#undef  TARGET_PRINT_OPERAND
203
#define TARGET_PRINT_OPERAND            iq2000_print_operand
204
#undef  TARGET_PRINT_OPERAND_ADDRESS
205
#define TARGET_PRINT_OPERAND_ADDRESS    iq2000_print_operand_address
206
#undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
207
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P iq2000_print_operand_punct_valid_p
208
 
209
#undef  TARGET_PROMOTE_FUNCTION_MODE
210
#define TARGET_PROMOTE_FUNCTION_MODE    default_promote_function_mode_always_promote
211
#undef  TARGET_PROMOTE_PROTOTYPES
212
#define TARGET_PROMOTE_PROTOTYPES       hook_bool_const_tree_true
213
 
214
#undef TARGET_FUNCTION_VALUE
215
#define TARGET_FUNCTION_VALUE           iq2000_function_value
216
#undef TARGET_LIBCALL_VALUE
217
#define TARGET_LIBCALL_VALUE            iq2000_libcall_value
218
#undef  TARGET_RETURN_IN_MEMORY
219
#define TARGET_RETURN_IN_MEMORY         iq2000_return_in_memory
220
#undef  TARGET_PASS_BY_REFERENCE
221
#define TARGET_PASS_BY_REFERENCE        iq2000_pass_by_reference
222
#undef  TARGET_CALLEE_COPIES
223
#define TARGET_CALLEE_COPIES            hook_callee_copies_named
224
#undef  TARGET_ARG_PARTIAL_BYTES
225
#define TARGET_ARG_PARTIAL_BYTES        iq2000_arg_partial_bytes
226
#undef  TARGET_FUNCTION_ARG
227
#define TARGET_FUNCTION_ARG             iq2000_function_arg
228
#undef  TARGET_FUNCTION_ARG_ADVANCE
229
#define TARGET_FUNCTION_ARG_ADVANCE     iq2000_function_arg_advance
230
#undef  TARGET_FUNCTION_ARG_BOUNDARY
231
#define TARGET_FUNCTION_ARG_BOUNDARY    iq2000_function_arg_boundary
232
 
233
#undef  TARGET_SETUP_INCOMING_VARARGS
234
#define TARGET_SETUP_INCOMING_VARARGS   iq2000_setup_incoming_varargs
235
#undef  TARGET_STRICT_ARGUMENT_NAMING
236
#define TARGET_STRICT_ARGUMENT_NAMING   hook_bool_CUMULATIVE_ARGS_true
237
 
238
#undef  TARGET_EXPAND_BUILTIN_VA_START
239
#define TARGET_EXPAND_BUILTIN_VA_START  iq2000_va_start
240
 
241
#undef TARGET_LEGITIMATE_ADDRESS_P
242
#define TARGET_LEGITIMATE_ADDRESS_P     iq2000_legitimate_address_p
243
 
244
#undef TARGET_CAN_ELIMINATE
245
#define TARGET_CAN_ELIMINATE            iq2000_can_eliminate
246
 
247
#undef  TARGET_ASM_TRAMPOLINE_TEMPLATE
248
#define TARGET_ASM_TRAMPOLINE_TEMPLATE  iq2000_asm_trampoline_template
249
#undef  TARGET_TRAMPOLINE_INIT
250
#define TARGET_TRAMPOLINE_INIT          iq2000_trampoline_init
251
 
252
struct gcc_target targetm = TARGET_INITIALIZER;
253
 
254
/* Return nonzero if we split the address into high and low parts.  */
255
 
256
int
257
iq2000_check_split (rtx address, enum machine_mode mode)
258
{
259
  /* This is the same check used in simple_memory_operand.
260
     We use it here because LO_SUM is not offsettable.  */
261
  if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD)
262
    return 0;
263
 
264
  if ((GET_CODE (address) == SYMBOL_REF)
265
      || (GET_CODE (address) == CONST
266
          && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF)
267
      || GET_CODE (address) == LABEL_REF)
268
    return 1;
269
 
270
  return 0;
271
}
272
 
273
/* Return nonzero if REG is valid for MODE.  */
274
 
275
int
276
iq2000_reg_mode_ok_for_base_p (rtx reg,
277
                               enum machine_mode mode ATTRIBUTE_UNUSED,
278
                               int strict)
279
{
280
  return (strict
281
          ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
282
          : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
283
}
284
 
285
/* Return a nonzero value if XINSN is a legitimate address for a
286
   memory operand of the indicated MODE.  STRICT is nonzero if this
287
   function is called during reload.  */
288
 
289
bool
290
iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
291
{
292
  if (TARGET_DEBUG_A_MODE)
293
    {
294
      GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
295
                  strict ? "" : "not ");
296
      GO_DEBUG_RTX (xinsn);
297
    }
298
 
299
  /* Check for constant before stripping off SUBREG, so that we don't
300
     accept (subreg (const_int)) which will fail to reload.  */
301
  if (CONSTANT_ADDRESS_P (xinsn)
302
      && ! (iq2000_check_split (xinsn, mode))
303
      && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn)))
304
    return 1;
305
 
306
  while (GET_CODE (xinsn) == SUBREG)
307
    xinsn = SUBREG_REG (xinsn);
308
 
309
  if (GET_CODE (xinsn) == REG
310
      && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict))
311
    return 1;
312
 
313
  if (GET_CODE (xinsn) == LO_SUM)
314
    {
315
      rtx xlow0 = XEXP (xinsn, 0);
316
      rtx xlow1 = XEXP (xinsn, 1);
317
 
318
      while (GET_CODE (xlow0) == SUBREG)
319
        xlow0 = SUBREG_REG (xlow0);
320
      if (GET_CODE (xlow0) == REG
321
          && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict)
322
          && iq2000_check_split (xlow1, mode))
323
        return 1;
324
    }
325
 
326
  if (GET_CODE (xinsn) == PLUS)
327
    {
328
      rtx xplus0 = XEXP (xinsn, 0);
329
      rtx xplus1 = XEXP (xinsn, 1);
330
      enum rtx_code code0;
331
      enum rtx_code code1;
332
 
333
      while (GET_CODE (xplus0) == SUBREG)
334
        xplus0 = SUBREG_REG (xplus0);
335
      code0 = GET_CODE (xplus0);
336
 
337
      while (GET_CODE (xplus1) == SUBREG)
338
        xplus1 = SUBREG_REG (xplus1);
339
      code1 = GET_CODE (xplus1);
340
 
341
      if (code0 == REG
342
          && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict))
343
        {
344
          if (code1 == CONST_INT && SMALL_INT (xplus1)
345
              && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */)
346
            return 1;
347
        }
348
    }
349
 
350
  if (TARGET_DEBUG_A_MODE)
351
    GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
352
 
353
  /* The address was not legitimate.  */
354
  return 0;
355
}
356
 
357
/* Returns an operand string for the given instruction's delay slot,
358
   after updating filled delay slot statistics.
359
 
360
   We assume that operands[0] is the target register that is set.
361
 
362
   In order to check the next insn, most of this functionality is moved
363
   to FINAL_PRESCAN_INSN, and we just set the global variables that
364
   it needs.  */
365
 
366
const char *
367
iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
368
                        rtx cur_insn)
369
{
370
  rtx set_reg;
371
  enum machine_mode mode;
372
  rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
373
  int num_nops;
374
 
375
  if (type == DELAY_LOAD || type == DELAY_FCMP)
376
    num_nops = 1;
377
 
378
  else
379
    num_nops = 0;
380
 
381
  /* Make sure that we don't put nop's after labels.  */
382
  next_insn = NEXT_INSN (cur_insn);
383
  while (next_insn != 0
384
         && (GET_CODE (next_insn) == NOTE
385
             || GET_CODE (next_insn) == CODE_LABEL))
386
    next_insn = NEXT_INSN (next_insn);
387
 
388
  dslots_load_total += num_nops;
389
  if (TARGET_DEBUG_C_MODE
390
      || type == DELAY_NONE
391
      || operands == 0
392
      || cur_insn == 0
393
      || next_insn == 0
394
      || GET_CODE (next_insn) == CODE_LABEL
395
      || (set_reg = operands[0]) == 0)
396
    {
397
      dslots_number_nops = 0;
398
      iq2000_load_reg  = 0;
399
      iq2000_load_reg2 = 0;
400
      iq2000_load_reg3 = 0;
401
      iq2000_load_reg4 = 0;
402
 
403
      return ret;
404
    }
405
 
406
  set_reg = operands[0];
407
  if (set_reg == 0)
408
    return ret;
409
 
410
  while (GET_CODE (set_reg) == SUBREG)
411
    set_reg = SUBREG_REG (set_reg);
412
 
413
  mode = GET_MODE (set_reg);
414
  dslots_number_nops = num_nops;
415
  iq2000_load_reg = set_reg;
416
  if (GET_MODE_SIZE (mode)
417
      > (unsigned) (UNITS_PER_WORD))
418
    iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1);
419
  else
420
    iq2000_load_reg2 = 0;
421
 
422
  return ret;
423
}
424
 
425
/* Determine whether a memory reference takes one (based off of the GP
426
   pointer), two (normal), or three (label + reg) instructions, and bump the
427
   appropriate counter for -mstats.  */
428
 
429
static void
430
iq2000_count_memory_refs (rtx op, int num)
431
{
432
  int additional = 0;
433
  int n_words = 0;
434
  rtx addr, plus0, plus1;
435
  enum rtx_code code0, code1;
436
  int looping;
437
 
438
  if (TARGET_DEBUG_B_MODE)
439
    {
440
      fprintf (stderr, "\n========== iq2000_count_memory_refs:\n");
441
      debug_rtx (op);
442
    }
443
 
444
  /* Skip MEM if passed, otherwise handle movsi of address.  */
445
  addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
446
 
447
  /* Loop, going through the address RTL.  */
448
  do
449
    {
450
      looping = FALSE;
451
      switch (GET_CODE (addr))
452
        {
453
        case REG:
454
        case CONST_INT:
455
        case LO_SUM:
456
          break;
457
 
458
        case PLUS:
459
          plus0 = XEXP (addr, 0);
460
          plus1 = XEXP (addr, 1);
461
          code0 = GET_CODE (plus0);
462
          code1 = GET_CODE (plus1);
463
 
464
          if (code0 == REG)
465
            {
466
              additional++;
467
              addr = plus1;
468
              looping = 1;
469
              continue;
470
            }
471
 
472
          if (code0 == CONST_INT)
473
            {
474
              addr = plus1;
475
              looping = 1;
476
              continue;
477
            }
478
 
479
          if (code1 == REG)
480
            {
481
              additional++;
482
              addr = plus0;
483
              looping = 1;
484
              continue;
485
            }
486
 
487
          if (code1 == CONST_INT)
488
            {
489
              addr = plus0;
490
              looping = 1;
491
              continue;
492
            }
493
 
494
          if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
495
            {
496
              addr = plus0;
497
              looping = 1;
498
              continue;
499
            }
500
 
501
          if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
502
            {
503
              addr = plus1;
504
              looping = 1;
505
              continue;
506
            }
507
 
508
          break;
509
 
510
        case LABEL_REF:
511
          n_words = 2;          /* Always 2 words.  */
512
          break;
513
 
514
        case CONST:
515
          addr = XEXP (addr, 0);
516
          looping = 1;
517
          continue;
518
 
519
        case SYMBOL_REF:
520
          n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
521
          break;
522
 
523
        default:
524
          break;
525
        }
526
    }
527
  while (looping);
528
 
529
  if (n_words == 0)
530
    return;
531
 
532
  n_words += additional;
533
  if (n_words > 3)
534
    n_words = 3;
535
 
536
  num_refs[n_words-1] += num;
537
}
538
 
539
/* Abort after printing out a specific insn.  */
540
 
541
static void
542
abort_with_insn (rtx insn, const char * reason)
543
{
544
  error (reason);
545
  debug_rtx (insn);
546
  fancy_abort (__FILE__, __LINE__, __FUNCTION__);
547
}
548
 
549
/* Return the appropriate instructions to move one operand to another.  */
550
 
551
const char *
552
iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
553
{
554
  const char *ret = 0;
555
  rtx op0 = operands[0];
556
  rtx op1 = operands[1];
557
  enum rtx_code code0 = GET_CODE (op0);
558
  enum rtx_code code1 = GET_CODE (op1);
559
  enum machine_mode mode = GET_MODE (op0);
560
  int subreg_offset0 = 0;
561
  int subreg_offset1 = 0;
562
  enum delay_type delay = DELAY_NONE;
563
 
564
  while (code0 == SUBREG)
565
    {
566
      subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),
567
                                             GET_MODE (SUBREG_REG (op0)),
568
                                             SUBREG_BYTE (op0),
569
                                             GET_MODE (op0));
570
      op0 = SUBREG_REG (op0);
571
      code0 = GET_CODE (op0);
572
    }
573
 
574
  while (code1 == SUBREG)
575
    {
576
      subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),
577
                                             GET_MODE (SUBREG_REG (op1)),
578
                                             SUBREG_BYTE (op1),
579
                                             GET_MODE (op1));
580
      op1 = SUBREG_REG (op1);
581
      code1 = GET_CODE (op1);
582
    }
583
 
584
  /* For our purposes, a condition code mode is the same as SImode.  */
585
  if (mode == CCmode)
586
    mode = SImode;
587
 
588
  if (code0 == REG)
589
    {
590
      int regno0 = REGNO (op0) + subreg_offset0;
591
 
592
      if (code1 == REG)
593
        {
594
          int regno1 = REGNO (op1) + subreg_offset1;
595
 
596
          /* Do not do anything for assigning a register to itself */
597
          if (regno0 == regno1)
598
            ret = "";
599
 
600
          else if (GP_REG_P (regno0))
601
            {
602
              if (GP_REG_P (regno1))
603
                ret = "or\t%0,%%0,%1";
604
            }
605
 
606
        }
607
 
608
      else if (code1 == MEM)
609
        {
610
          delay = DELAY_LOAD;
611
 
612
          if (TARGET_STATS)
613
            iq2000_count_memory_refs (op1, 1);
614
 
615
          if (GP_REG_P (regno0))
616
            {
617
              /* For loads, use the mode of the memory item, instead of the
618
                 target, so zero/sign extend can use this code as well.  */
619
              switch (GET_MODE (op1))
620
                {
621
                default:
622
                  break;
623
                case SFmode:
624
                  ret = "lw\t%0,%1";
625
                  break;
626
                case SImode:
627
                case CCmode:
628
                  ret = "lw\t%0,%1";
629
                  break;
630
                case HImode:
631
                  ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
632
                  break;
633
                case QImode:
634
                  ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
635
                  break;
636
                }
637
            }
638
        }
639
 
640
      else if (code1 == CONST_INT
641
               || (code1 == CONST_DOUBLE
642
                   && GET_MODE (op1) == VOIDmode))
643
        {
644
          if (code1 == CONST_DOUBLE)
645
            {
646
              /* This can happen when storing constants into long long
647
                 bitfields.  Just store the least significant word of
648
                 the value.  */
649
              operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
650
            }
651
 
652
          if (INTVAL (op1) == 0)
653
            {
654
              if (GP_REG_P (regno0))
655
                ret = "or\t%0,%%0,%z1";
656
            }
657
         else if (GP_REG_P (regno0))
658
            {
659
              if (SMALL_INT_UNSIGNED (op1))
660
                ret = "ori\t%0,%%0,%x1\t\t\t# %1";
661
              else if (SMALL_INT (op1))
662
                ret = "addiu\t%0,%%0,%1\t\t\t# %1";
663
              else
664
                ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1";
665
            }
666
        }
667
 
668
      else if (code1 == CONST_DOUBLE && mode == SFmode)
669
        {
670
          if (op1 == CONST0_RTX (SFmode))
671
            {
672
              if (GP_REG_P (regno0))
673
                ret = "or\t%0,%%0,%.";
674
            }
675
 
676
          else
677
            {
678
              delay = DELAY_LOAD;
679
              ret = "li.s\t%0,%1";
680
            }
681
        }
682
 
683
      else if (code1 == LABEL_REF)
684
        {
685
          if (TARGET_STATS)
686
            iq2000_count_memory_refs (op1, 1);
687
 
688
          ret = "la\t%0,%a1";
689
        }
690
 
691
      else if (code1 == SYMBOL_REF || code1 == CONST)
692
        {
693
          if (TARGET_STATS)
694
            iq2000_count_memory_refs (op1, 1);
695
 
696
          ret = "la\t%0,%a1";
697
        }
698
 
699
      else if (code1 == PLUS)
700
        {
701
          rtx add_op0 = XEXP (op1, 0);
702
          rtx add_op1 = XEXP (op1, 1);
703
 
704
          if (GET_CODE (XEXP (op1, 1)) == REG
705
              && GET_CODE (XEXP (op1, 0)) == CONST_INT)
706
            add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);
707
 
708
          operands[2] = add_op0;
709
          operands[3] = add_op1;
710
          ret = "add%:\t%0,%2,%3";
711
        }
712
 
713
      else if (code1 == HIGH)
714
        {
715
          operands[1] = XEXP (op1, 0);
716
          ret = "lui\t%0,%%hi(%1)";
717
        }
718
    }
719
 
720
  else if (code0 == MEM)
721
    {
722
      if (TARGET_STATS)
723
        iq2000_count_memory_refs (op0, 1);
724
 
725
      if (code1 == REG)
726
        {
727
          int regno1 = REGNO (op1) + subreg_offset1;
728
 
729
          if (GP_REG_P (regno1))
730
            {
731
              switch (mode)
732
                {
733
                case SFmode: ret = "sw\t%1,%0"; break;
734
                case SImode: ret = "sw\t%1,%0"; break;
735
                case HImode: ret = "sh\t%1,%0"; break;
736
                case QImode: ret = "sb\t%1,%0"; break;
737
                default: break;
738
                }
739
            }
740
        }
741
 
742
      else if (code1 == CONST_INT && INTVAL (op1) == 0)
743
        {
744
          switch (mode)
745
            {
746
            case SFmode: ret = "sw\t%z1,%0"; break;
747
            case SImode: ret = "sw\t%z1,%0"; break;
748
            case HImode: ret = "sh\t%z1,%0"; break;
749
            case QImode: ret = "sb\t%z1,%0"; break;
750
            default: break;
751
            }
752
        }
753
 
754
      else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))
755
        {
756
          switch (mode)
757
            {
758
            case SFmode: ret = "sw\t%.,%0"; break;
759
            case SImode: ret = "sw\t%.,%0"; break;
760
            case HImode: ret = "sh\t%.,%0"; break;
761
            case QImode: ret = "sb\t%.,%0"; break;
762
            default: break;
763
            }
764
        }
765
    }
766
 
767
  if (ret == 0)
768
    {
769
      abort_with_insn (insn, "Bad move");
770
      return 0;
771
    }
772
 
773
  if (delay != DELAY_NONE)
774
    return iq2000_fill_delay_slot (ret, delay, operands, insn);
775
 
776
  return ret;
777
}
778
 
779
/* Provide the costs of an addressing mode that contains ADDR.  */
780
 
781
static int
782
iq2000_address_cost (rtx addr, bool speed)
783
{
784
  switch (GET_CODE (addr))
785
    {
786
    case LO_SUM:
787
      return 1;
788
 
789
    case LABEL_REF:
790
      return 2;
791
 
792
    case CONST:
793
      {
794
        rtx offset = const0_rtx;
795
 
796
        addr = eliminate_constant_term (XEXP (addr, 0), & offset);
797
        if (GET_CODE (addr) == LABEL_REF)
798
          return 2;
799
 
800
        if (GET_CODE (addr) != SYMBOL_REF)
801
          return 4;
802
 
803
        if (! SMALL_INT (offset))
804
          return 2;
805
      }
806
 
807
      /* Fall through.  */
808
 
809
    case SYMBOL_REF:
810
      return SYMBOL_REF_FLAG (addr) ? 1 : 2;
811
 
812
    case PLUS:
813
      {
814
        rtx plus0 = XEXP (addr, 0);
815
        rtx plus1 = XEXP (addr, 1);
816
 
817
        if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
818
          plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0);
819
 
820
        if (GET_CODE (plus0) != REG)
821
          break;
822
 
823
        switch (GET_CODE (plus1))
824
          {
825
          case CONST_INT:
826
            return SMALL_INT (plus1) ? 1 : 2;
827
 
828
          case CONST:
829
          case SYMBOL_REF:
830
          case LABEL_REF:
831
          case HIGH:
832
          case LO_SUM:
833
            return iq2000_address_cost (plus1, speed) + 1;
834
 
835
          default:
836
            break;
837
          }
838
      }
839
 
840
    default:
841
      break;
842
    }
843
 
844
  return 4;
845
}
846
 
847
/* Make normal rtx_code into something we can index from an array.  */
848
 
849
static enum internal_test
850
map_test_to_internal_test (enum rtx_code test_code)
851
{
852
  enum internal_test test = ITEST_MAX;
853
 
854
  switch (test_code)
855
    {
856
    case EQ:  test = ITEST_EQ;  break;
857
    case NE:  test = ITEST_NE;  break;
858
    case GT:  test = ITEST_GT;  break;
859
    case GE:  test = ITEST_GE;  break;
860
    case LT:  test = ITEST_LT;  break;
861
    case LE:  test = ITEST_LE;  break;
862
    case GTU: test = ITEST_GTU; break;
863
    case GEU: test = ITEST_GEU; break;
864
    case LTU: test = ITEST_LTU; break;
865
    case LEU: test = ITEST_LEU; break;
866
    default:                    break;
867
    }
868
 
869
  return test;
870
}
871
 
872
/* Generate the code to do a TEST_CODE comparison on two integer values CMP0
873
   and CMP1.  P_INVERT is NULL or ptr if branch needs to reverse its test.
874
   The return value RESULT is:
875
   (reg:SI xx)          The pseudo register the comparison is in
876
 
877
 
878
rtx
879
gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
880
                    int *p_invert)
881
{
882
  struct cmp_info
883
  {
884
    enum rtx_code test_code;    /* Code to use in instruction (LT vs. LTU).  */
885
    int const_low;              /* Low bound of constant we can accept.  */
886
    int const_high;             /* High bound of constant we can accept.  */
887
    int const_add;              /* Constant to add (convert LE -> LT).  */
888
    int reverse_regs;           /* Reverse registers in test.  */
889
    int invert_const;           /* != 0 if invert value if cmp1 is constant.  */
890
    int invert_reg;             /* != 0 if invert value if cmp1 is register.  */
891
    int unsignedp;              /* != 0 for unsigned comparisons.  */
892
  };
893
 
894
  static struct cmp_info info[ (int)ITEST_MAX ] =
895
  {
896
    { XOR,       0,  65535,  0,    0,  0,    0, 0 },  /* EQ  */
897
    { XOR,       0,  65535,  0,    0,  1,   1, 0 }, /* NE  */
898
    { LT,   -32769,  32766,  1,  1,  1,  0, 0 },  /* GT  */
899
    { LT,   -32768,  32767,  0,   0,  1,   1, 0 }, /* GE  */
900
    { LT,   -32768,  32767,  0,   0,  0,    0, 0 },  /* LT  */
901
    { LT,   -32769,  32766,  1,  1,  0,   1, 0 }, /* LE  */
902
    { LTU,  -32769,  32766,  1,  1,  1,  0, 1 }, /* GTU */
903
    { LTU,  -32768,  32767,  0,   0,  1,   1, 1 },        /* GEU */
904
    { LTU,  -32768,  32767,  0,   0,  0,    0, 1 }, /* LTU */
905
    { LTU,  -32769,  32766,  1,  1,  0,   1, 1 },        /* LEU */
906
  };
907
 
908
  enum internal_test test;
909
  enum machine_mode mode;
910
  struct cmp_info *p_info;
911
  int branch_p;
912
  int eqne_p;
913
  int invert;
914
  rtx reg;
915
  rtx reg2;
916
 
917
  test = map_test_to_internal_test (test_code);
918
  gcc_assert (test != ITEST_MAX);
919
 
920
  p_info = &info[(int) test];
921
  eqne_p = (p_info->test_code == XOR);
922
 
923
  mode = GET_MODE (cmp0);
924
  if (mode == VOIDmode)
925
    mode = GET_MODE (cmp1);
926
 
927
  /* Eliminate simple branches.  */
928
  branch_p = (result == 0);
929
  if (branch_p)
930
    {
931
      if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
932
        {
933
          /* Comparisons against zero are simple branches.  */
934
          if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
935
            return 0;
936
 
937
          /* Test for beq/bne.  */
938
          if (eqne_p)
939
            return 0;
940
        }
941
 
942
      /* Allocate a pseudo to calculate the value in.  */
943
      result = gen_reg_rtx (mode);
944
    }
945
 
946
  /* Make sure we can handle any constants given to us.  */
947
  if (GET_CODE (cmp0) == CONST_INT)
948
    cmp0 = force_reg (mode, cmp0);
949
 
950
  if (GET_CODE (cmp1) == CONST_INT)
951
    {
952
      HOST_WIDE_INT value = INTVAL (cmp1);
953
 
954
      if (value < p_info->const_low
955
          || value > p_info->const_high)
956
        cmp1 = force_reg (mode, cmp1);
957
    }
958
 
959
  /* See if we need to invert the result.  */
960
  invert = (GET_CODE (cmp1) == CONST_INT
961
            ? p_info->invert_const : p_info->invert_reg);
962
 
963
  if (p_invert != (int *)0)
964
    {
965
      *p_invert = invert;
966
      invert = 0;
967
    }
968
 
969
  /* Comparison to constants, may involve adding 1 to change a LT into LE.
970
     Comparison between two registers, may involve switching operands.  */
971
  if (GET_CODE (cmp1) == CONST_INT)
972
    {
973
      if (p_info->const_add != 0)
974
        {
975
          HOST_WIDE_INT new_const = INTVAL (cmp1) + p_info->const_add;
976
 
977
          /* If modification of cmp1 caused overflow,
978
             we would get the wrong answer if we follow the usual path;
979
             thus, x > 0xffffffffU would turn into x > 0U.  */
980
          if ((p_info->unsignedp
981
               ? (unsigned HOST_WIDE_INT) new_const >
982
               (unsigned HOST_WIDE_INT) INTVAL (cmp1)
983
               : new_const > INTVAL (cmp1))
984
              != (p_info->const_add > 0))
985
            {
986
              /* This test is always true, but if INVERT is true then
987
                 the result of the test needs to be inverted so 0 should
988
                 be returned instead.  */
989
              emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
990
              return result;
991
            }
992
          else
993
            cmp1 = GEN_INT (new_const);
994
        }
995
    }
996
 
997
  else if (p_info->reverse_regs)
998
    {
999
      rtx temp = cmp0;
1000
      cmp0 = cmp1;
1001
      cmp1 = temp;
1002
    }
1003
 
1004
  if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1005
    reg = cmp0;
1006
  else
1007
    {
1008
      reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result;
1009
      convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0);
1010
    }
1011
 
1012
  if (test == ITEST_NE)
1013
    {
1014
      convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0);
1015
      if (p_invert != NULL)
1016
        *p_invert = 0;
1017
      invert = 0;
1018
    }
1019
 
1020
  else if (test == ITEST_EQ)
1021
    {
1022
      reg2 = invert ? gen_reg_rtx (mode) : result;
1023
      convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
1024
      reg = reg2;
1025
    }
1026
 
1027
  if (invert)
1028
    {
1029
      rtx one;
1030
 
1031
      one = const1_rtx;
1032
      convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
1033
    }
1034
 
1035
  return result;
1036
}
1037
 
1038
/* Emit the common code for doing conditional branches.
1039
   operand[0] is the label to jump to.
1040
   The comparison operands are saved away by cmp{si,di,sf,df}.  */
1041
 
1042
void
1043
gen_conditional_branch (rtx operands[], enum machine_mode mode)
1044
{
1045
  enum rtx_code test_code = GET_CODE (operands[0]);
1046
  rtx cmp0 = operands[1];
1047
  rtx cmp1 = operands[2];
1048
  rtx reg;
1049
  int invert;
1050
  rtx label1, label2;
1051
 
1052
  invert = 0;
1053
  reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
1054
 
1055
  if (reg)
1056
    {
1057
      cmp0 = reg;
1058
      cmp1 = const0_rtx;
1059
      test_code = NE;
1060
    }
1061
  else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1062
    /* We don't want to build a comparison against a nonzero
1063
       constant.  */
1064
    cmp1 = force_reg (mode, cmp1);
1065
 
1066
  /* Generate the branch.  */
1067
  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1068
  label2 = pc_rtx;
1069
 
1070
  if (invert)
1071
    {
1072
      label2 = label1;
1073
      label1 = pc_rtx;
1074
    }
1075
 
1076
  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1077
                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1078
                                                     gen_rtx_fmt_ee (test_code,
1079
                                                                     mode,
1080
                                                                     cmp0, cmp1),
1081
                                                     label1, label2)));
1082
}
1083
 
1084
/* Initialize CUM for a function FNTYPE.  */
1085
 
1086
void
1087
init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
1088
                      rtx libname ATTRIBUTE_UNUSED)
1089
{
1090
  static CUMULATIVE_ARGS zero_cum;
1091
  tree param;
1092
  tree next_param;
1093
 
1094
  if (TARGET_DEBUG_D_MODE)
1095
    {
1096
      fprintf (stderr,
1097
               "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype);
1098
 
1099
      if (!fntype)
1100
        fputc ('\n', stderr);
1101
 
1102
      else
1103
        {
1104
          tree ret_type = TREE_TYPE (fntype);
1105
 
1106
          fprintf (stderr, ", fntype code = %s, ret code = %s\n",
1107
                   tree_code_name[(int)TREE_CODE (fntype)],
1108
                   tree_code_name[(int)TREE_CODE (ret_type)]);
1109
        }
1110
    }
1111
 
1112
  *cum = zero_cum;
1113
 
1114
  /* Determine if this function has variable arguments.  This is
1115
     indicated by the last argument being 'void_type_mode' if there
1116
     are no variable arguments.  The standard IQ2000 calling sequence
1117
     passes all arguments in the general purpose registers in this case.  */
1118
 
1119
  for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
1120
       param != 0; param = next_param)
1121
    {
1122
      next_param = TREE_CHAIN (param);
1123
      if (next_param == 0 && TREE_VALUE (param) != void_type_node)
1124
        cum->gp_reg_found = 1;
1125
    }
1126
}
1127
 
1128
/* Advance the argument of type TYPE and mode MODE to the next argument
1129
   position in CUM.  */
1130
 
1131
static void
1132
iq2000_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1133
                             const_tree type, bool named)
1134
{
1135
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1136
 
1137
  if (TARGET_DEBUG_D_MODE)
1138
    {
1139
      fprintf (stderr,
1140
               "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1141
               cum->gp_reg_found, cum->arg_number, cum->arg_words,
1142
               GET_MODE_NAME (mode));
1143
      fprintf (stderr, "%p", CONST_CAST2 (void *, const_tree,  type));
1144
      fprintf (stderr, ", %d )\n\n", named);
1145
    }
1146
 
1147
  cum->arg_number++;
1148
  switch (mode)
1149
    {
1150
    case VOIDmode:
1151
      break;
1152
 
1153
    default:
1154
      gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1155
                  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1156
 
1157
      cum->gp_reg_found = 1;
1158
      cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
1159
                         / UNITS_PER_WORD);
1160
      break;
1161
 
1162
    case BLKmode:
1163
      cum->gp_reg_found = 1;
1164
      cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
1165
                         / UNITS_PER_WORD);
1166
      break;
1167
 
1168
    case SFmode:
1169
      cum->arg_words ++;
1170
      if (! cum->gp_reg_found && cum->arg_number <= 2)
1171
        cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
1172
      break;
1173
 
1174
    case DFmode:
1175
      cum->arg_words += 2;
1176
      if (! cum->gp_reg_found && cum->arg_number <= 2)
1177
        cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
1178
      break;
1179
 
1180
    case DImode:
1181
      cum->gp_reg_found = 1;
1182
      cum->arg_words += 2;
1183
      break;
1184
 
1185
    case TImode:
1186
      cum->gp_reg_found = 1;
1187
      cum->arg_words += 4;
1188
      break;
1189
 
1190
    case QImode:
1191
    case HImode:
1192
    case SImode:
1193
      cum->gp_reg_found = 1;
1194
      cum->arg_words ++;
1195
      break;
1196
    }
1197
}
1198
 
1199
/* Return an RTL expression containing the register for the given mode MODE
1200
   and type TYPE in CUM, or 0 if the argument is to be passed on the stack.  */
1201
 
1202
static rtx
1203
iq2000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1204
                     const_tree type, bool named)
1205
{
1206
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1207
  rtx ret;
1208
  int regbase = -1;
1209
  int bias = 0;
1210
  unsigned int *arg_words = &cum->arg_words;
1211
  int struct_p = (type != 0
1212
                  && (TREE_CODE (type) == RECORD_TYPE
1213
                      || TREE_CODE (type) == UNION_TYPE
1214
                      || TREE_CODE (type) == QUAL_UNION_TYPE));
1215
 
1216
  if (TARGET_DEBUG_D_MODE)
1217
    {
1218
      fprintf (stderr,
1219
               "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
1220
               cum->gp_reg_found, cum->arg_number, cum->arg_words,
1221
               GET_MODE_NAME (mode));
1222
      fprintf (stderr, "%p", (const void *) type);
1223
      fprintf (stderr, ", %d ) = ", named);
1224
    }
1225
 
1226
 
1227
  cum->last_arg_fp = 0;
1228
  switch (mode)
1229
    {
1230
    case SFmode:
1231
      regbase = GP_ARG_FIRST;
1232
      break;
1233
 
1234
    case DFmode:
1235
      cum->arg_words += cum->arg_words & 1;
1236
 
1237
      regbase = GP_ARG_FIRST;
1238
      break;
1239
 
1240
    default:
1241
      gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
1242
                  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1243
 
1244
      /* Drops through.  */
1245
    case BLKmode:
1246
      if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
1247
        cum->arg_words += (cum->arg_words & 1);
1248
      regbase = GP_ARG_FIRST;
1249
      break;
1250
 
1251
    case VOIDmode:
1252
    case QImode:
1253
    case HImode:
1254
    case SImode:
1255
      regbase = GP_ARG_FIRST;
1256
      break;
1257
 
1258
    case DImode:
1259
      cum->arg_words += (cum->arg_words & 1);
1260
      regbase = GP_ARG_FIRST;
1261
      break;
1262
 
1263
    case TImode:
1264
      cum->arg_words += (cum->arg_words & 3);
1265
      regbase = GP_ARG_FIRST;
1266
      break;
1267
    }
1268
 
1269
  if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
1270
    {
1271
      if (TARGET_DEBUG_D_MODE)
1272
        fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : "");
1273
 
1274
      ret = 0;
1275
    }
1276
  else
1277
    {
1278
      gcc_assert (regbase != -1);
1279
 
1280
      if (! type || TREE_CODE (type) != RECORD_TYPE
1281
          || ! named  || ! TYPE_SIZE_UNIT (type)
1282
          || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1283
        ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1284
      else
1285
        {
1286
          tree field;
1287
 
1288
          for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1289
            if (TREE_CODE (field) == FIELD_DECL
1290
                && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1291
                && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
1292
                && host_integerp (bit_position (field), 0)
1293
                && int_bit_position (field) % BITS_PER_WORD == 0)
1294
              break;
1295
 
1296
          /* If the whole struct fits a DFmode register,
1297
             we don't need the PARALLEL.  */
1298
          if (! field || mode == DFmode)
1299
            ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
1300
          else
1301
            {
1302
              unsigned int chunks;
1303
              HOST_WIDE_INT bitpos;
1304
              unsigned int regno;
1305
              unsigned int i;
1306
 
1307
              /* ??? If this is a packed structure, then the last hunk won't
1308
                 be 64 bits.  */
1309
              chunks
1310
                = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
1311
              if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
1312
                chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
1313
 
1314
              /* Assign_parms checks the mode of ENTRY_PARM, so we must
1315
                 use the actual mode here.  */
1316
              ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));
1317
 
1318
              bitpos = 0;
1319
              regno = regbase + *arg_words + bias;
1320
              field = TYPE_FIELDS (type);
1321
              for (i = 0; i < chunks; i++)
1322
                {
1323
                  rtx reg;
1324
 
1325
                  for (; field; field = DECL_CHAIN (field))
1326
                    if (TREE_CODE (field) == FIELD_DECL
1327
                        && int_bit_position (field) >= bitpos)
1328
                      break;
1329
 
1330
                  if (field
1331
                      && int_bit_position (field) == bitpos
1332
                      && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
1333
                      && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
1334
                    reg = gen_rtx_REG (DFmode, regno++);
1335
                  else
1336
                    reg = gen_rtx_REG (word_mode, regno);
1337
 
1338
                  XVECEXP (ret, 0, i)
1339
                    = gen_rtx_EXPR_LIST (VOIDmode, reg,
1340
                                         GEN_INT (bitpos / BITS_PER_UNIT));
1341
 
1342
                  bitpos += 64;
1343
                  regno++;
1344
                }
1345
            }
1346
        }
1347
 
1348
      if (TARGET_DEBUG_D_MODE)
1349
        fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],
1350
                 struct_p ? ", [struct]" : "");
1351
    }
1352
 
1353
  /* We will be called with a mode of VOIDmode after the last argument
1354
     has been seen.  Whatever we return will be passed to the call
1355
     insn.  If we need any shifts for small structures, return them in
1356
     a PARALLEL.  */
1357
  if (mode == VOIDmode)
1358
    {
1359
      if (cum->num_adjusts > 0)
1360
        ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
1361
                       gen_rtvec_v (cum->num_adjusts, cum->adjust));
1362
    }
1363
 
1364
  return ret;
1365
}
1366
 
1367
static unsigned int
1368
iq2000_function_arg_boundary (enum machine_mode mode, const_tree type)
1369
{
1370
  return (type != NULL_TREE
1371
          ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
1372
             ? PARM_BOUNDARY
1373
             : TYPE_ALIGN (type))
1374
          : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY
1375
             ? PARM_BOUNDARY
1376
             : GET_MODE_ALIGNMENT (mode)));
1377
}
1378
 
1379
static int
1380
iq2000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
1381
                          tree type ATTRIBUTE_UNUSED,
1382
                          bool named ATTRIBUTE_UNUSED)
1383
{
1384
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1385
 
1386
  if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
1387
    {
1388
      if (TARGET_DEBUG_D_MODE)
1389
        fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);
1390
      return UNITS_PER_WORD;
1391
    }
1392
 
1393
  return 0;
1394
}
1395
 
1396
/* Implement va_start.  */
1397
 
1398
static void
1399
iq2000_va_start (tree valist, rtx nextarg)
1400
{
1401
  int int_arg_words;
1402
  /* Find out how many non-float named formals.  */
1403
  int gpr_save_area_size;
1404
  /* Note UNITS_PER_WORD is 4 bytes.  */
1405
  int_arg_words = crtl->args.info.arg_words;
1406
 
1407
  if (int_arg_words < 8 )
1408
    /* Adjust for the prologue's economy measure.  */
1409
    gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;
1410
  else
1411
    gpr_save_area_size = 0;
1412
 
1413
  /* Everything is in the GPR save area, or in the overflow
1414
     area which is contiguous with it.  */
1415
  nextarg = plus_constant (nextarg, - gpr_save_area_size);
1416
  std_expand_builtin_va_start (valist, nextarg);
1417
}
1418
 
1419
/* Allocate a chunk of memory for per-function machine-dependent data.  */
1420
 
1421
static struct machine_function *
1422
iq2000_init_machine_status (void)
1423
{
1424
  return ggc_alloc_cleared_machine_function ();
1425
}
1426
 
1427
/* Detect any conflicts in the switches.  */
1428
 
1429
static void
1430
iq2000_option_override (void)
1431
{
1432
  target_flags &= ~MASK_GPOPT;
1433
 
1434
  iq2000_isa = IQ2000_ISA_DEFAULT;
1435
 
1436
  /* Identify the processor type.  */
1437
 
1438
  iq2000_print_operand_punct['?'] = 1;
1439
  iq2000_print_operand_punct['#'] = 1;
1440
  iq2000_print_operand_punct['&'] = 1;
1441
  iq2000_print_operand_punct['!'] = 1;
1442
  iq2000_print_operand_punct['*'] = 1;
1443
  iq2000_print_operand_punct['@'] = 1;
1444
  iq2000_print_operand_punct['.'] = 1;
1445
  iq2000_print_operand_punct['('] = 1;
1446
  iq2000_print_operand_punct[')'] = 1;
1447
  iq2000_print_operand_punct['['] = 1;
1448
  iq2000_print_operand_punct[']'] = 1;
1449
  iq2000_print_operand_punct['<'] = 1;
1450
  iq2000_print_operand_punct['>'] = 1;
1451
  iq2000_print_operand_punct['{'] = 1;
1452
  iq2000_print_operand_punct['}'] = 1;
1453
  iq2000_print_operand_punct['^'] = 1;
1454
  iq2000_print_operand_punct['$'] = 1;
1455
  iq2000_print_operand_punct['+'] = 1;
1456
  iq2000_print_operand_punct['~'] = 1;
1457
 
1458
  /* Save GPR registers in word_mode sized hunks.  word_mode hasn't been
1459
     initialized yet, so we can't use that here.  */
1460
  gpr_mode = SImode;
1461
 
1462
  /* Function to allocate machine-dependent function status.  */
1463
  init_machine_status = iq2000_init_machine_status;
1464
}
1465
 
1466
/* The arg pointer (which is eliminated) points to the virtual frame pointer,
1467
   while the frame pointer (which may be eliminated) points to the stack
1468
   pointer after the initial adjustments.  */
1469
 
1470
HOST_WIDE_INT
1471
iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset)
1472
{
1473
  rtx offset2 = const0_rtx;
1474
  rtx reg = eliminate_constant_term (addr, & offset2);
1475
 
1476
  if (offset == 0)
1477
    offset = INTVAL (offset2);
1478
 
1479
  if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
1480
      || reg == hard_frame_pointer_rtx)
1481
    {
1482
      HOST_WIDE_INT frame_size = (!cfun->machine->initialized)
1483
                                  ? compute_frame_size (get_frame_size ())
1484
                                  : cfun->machine->total_size;
1485
 
1486
      offset = offset - frame_size;
1487
    }
1488
 
1489
  return offset;
1490
}
1491
 
1492
/* If defined, a C statement to be executed just prior to the output of
1493
   assembler code for INSN, to modify the extracted operands so they will be
1494
   output differently.
1495
 
1496
   Here the argument OPVEC is the vector containing the operands extracted
1497
   from INSN, and NOPERANDS is the number of elements of the vector which
1498
   contain meaningful data for this insn.  The contents of this vector are
1499
   what will be used to convert the insn template into assembler code, so you
1500
   can change the assembler output by changing the contents of the vector.
1501
 
1502
   We use it to check if the current insn needs a nop in front of it because
1503
   of load delays, and also to update the delay slot statistics.  */
1504
 
1505
void
1506
final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
1507
                    int noperands ATTRIBUTE_UNUSED)
1508
{
1509
  if (dslots_number_nops > 0)
1510
    {
1511
      rtx pattern = PATTERN (insn);
1512
      int length = get_attr_length (insn);
1513
 
1514
      /* Do we need to emit a NOP?  */
1515
      if (length == 0
1516
          || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg,  pattern))
1517
          || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))
1518
          || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))
1519
          || (iq2000_load_reg4 != 0
1520
              && reg_mentioned_p (iq2000_load_reg4, pattern)))
1521
        fputs ("\tnop\n", asm_out_file);
1522
 
1523
      else
1524
        dslots_load_filled ++;
1525
 
1526
      while (--dslots_number_nops > 0)
1527
        fputs ("\tnop\n", asm_out_file);
1528
 
1529
      iq2000_load_reg = 0;
1530
      iq2000_load_reg2 = 0;
1531
      iq2000_load_reg3 = 0;
1532
      iq2000_load_reg4 = 0;
1533
    }
1534
 
1535
  if (   (GET_CODE (insn) == JUMP_INSN
1536
       || GET_CODE (insn) == CALL_INSN
1537
       || (GET_CODE (PATTERN (insn)) == RETURN))
1538
           && NEXT_INSN (PREV_INSN (insn)) == insn)
1539
    {
1540
      rtx nop_insn = emit_insn_after (gen_nop (), insn);
1541
 
1542
      INSN_ADDRESSES_NEW (nop_insn, -1);
1543
    }
1544
 
1545
  if (TARGET_STATS
1546
      && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
1547
    dslots_jump_total ++;
1548
}
1549
 
1550
/* Return the bytes needed to compute the frame pointer from the current
1551
   stack pointer where SIZE is the # of var. bytes allocated.
1552
 
1553
   IQ2000 stack frames look like:
1554
 
1555
             Before call                        After call
1556
        +-----------------------+       +-----------------------+
1557
   high |                       |       |                       |
1558
   mem. |                       |       |                       |
1559
        |  caller's temps.      |       |  caller's temps.      |
1560
        |                       |       |                       |
1561
        +-----------------------+       +-----------------------+
1562
        |                       |       |                       |
1563
        |  arguments on stack.  |       |  arguments on stack.  |
1564
        |                       |       |                       |
1565
        +-----------------------+       +-----------------------+
1566
        |  4 words to save      |       |  4 words to save      |
1567
        |  arguments passed     |       |  arguments passed     |
1568
        |  in registers, even   |       |  in registers, even   |
1569
    SP->|  if not passed.       |  VFP->|  if not passed.       |
1570
        +-----------------------+       +-----------------------+
1571
                                        |                       |
1572
                                        |  fp register save     |
1573
                                        |                       |
1574
                                        +-----------------------+
1575
                                        |                       |
1576
                                        |  gp register save     |
1577
                                        |                       |
1578
                                        +-----------------------+
1579
                                        |                       |
1580
                                        |  local variables      |
1581
                                        |                       |
1582
                                        +-----------------------+
1583
                                        |                       |
1584
                                        |  alloca allocations   |
1585
                                        |                       |
1586
                                        +-----------------------+
1587
                                        |                       |
1588
                                        |  GP save for V.4 abi  |
1589
                                        |                       |
1590
                                        +-----------------------+
1591
                                        |                       |
1592
                                        |  arguments on stack   |
1593
                                        |                       |
1594
                                        +-----------------------+
1595
                                        |  4 words to save      |
1596
                                        |  arguments passed     |
1597
                                        |  in registers, even   |
1598
   low                              SP->|  if not passed.       |
1599
   memory                               +-----------------------+  */
1600
 
1601
HOST_WIDE_INT
1602
compute_frame_size (HOST_WIDE_INT size)
1603
{
1604
  int regno;
1605
  HOST_WIDE_INT total_size;     /* # bytes that the entire frame takes up.  */
1606
  HOST_WIDE_INT var_size;       /* # bytes that variables take up.  */
1607
  HOST_WIDE_INT args_size;      /* # bytes that outgoing arguments take up.  */
1608
  HOST_WIDE_INT extra_size;     /* # extra bytes.  */
1609
  HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding.  */
1610
  HOST_WIDE_INT gp_reg_size;    /* # bytes needed to store gp regs.  */
1611
  HOST_WIDE_INT fp_reg_size;    /* # bytes needed to store fp regs.  */
1612
  long mask;                    /* mask of saved gp registers.  */
1613
 
1614
  gp_reg_size = 0;
1615
  fp_reg_size = 0;
1616
  mask = 0;
1617
  extra_size = IQ2000_STACK_ALIGN ((0));
1618
  var_size = IQ2000_STACK_ALIGN (size);
1619
  args_size = IQ2000_STACK_ALIGN (crtl->outgoing_args_size);
1620
 
1621
  /* If a function dynamically allocates the stack and
1622
     has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space.  */
1623
  if (args_size == 0 && cfun->calls_alloca)
1624
    args_size = 4 * UNITS_PER_WORD;
1625
 
1626
  total_size = var_size + args_size + extra_size;
1627
 
1628
  /* Calculate space needed for gp registers.  */
1629
  for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
1630
    {
1631
      if (MUST_SAVE_REGISTER (regno))
1632
        {
1633
          gp_reg_size += GET_MODE_SIZE (gpr_mode);
1634
          mask |= 1L << (regno - GP_REG_FIRST);
1635
        }
1636
    }
1637
 
1638
  /* We need to restore these for the handler.  */
1639
  if (crtl->calls_eh_return)
1640
    {
1641
      unsigned int i;
1642
 
1643
      for (i = 0; ; ++i)
1644
        {
1645
          regno = EH_RETURN_DATA_REGNO (i);
1646
          if (regno == (int) INVALID_REGNUM)
1647
            break;
1648
          gp_reg_size += GET_MODE_SIZE (gpr_mode);
1649
          mask |= 1L << (regno - GP_REG_FIRST);
1650
        }
1651
    }
1652
 
1653
  gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);
1654
  total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);
1655
 
1656
  /* The gp reg is caller saved, so there is no need for leaf routines
1657
     (total_size == extra_size) to save the gp reg.  */
1658
  if (total_size == extra_size
1659
      && ! profile_flag)
1660
    total_size = extra_size = 0;
1661
 
1662
  total_size += IQ2000_STACK_ALIGN (crtl->args.pretend_args_size);
1663
 
1664
  /* Save other computed information.  */
1665
  cfun->machine->total_size = total_size;
1666
  cfun->machine->var_size = var_size;
1667
  cfun->machine->args_size = args_size;
1668
  cfun->machine->extra_size = extra_size;
1669
  cfun->machine->gp_reg_size = gp_reg_size;
1670
  cfun->machine->fp_reg_size = fp_reg_size;
1671
  cfun->machine->mask = mask;
1672
  cfun->machine->initialized = reload_completed;
1673
  cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;
1674
 
1675
  if (mask)
1676
    {
1677
      unsigned long offset;
1678
 
1679
      offset = (args_size + extra_size + var_size
1680
                + gp_reg_size - GET_MODE_SIZE (gpr_mode));
1681
 
1682
      cfun->machine->gp_sp_offset = offset;
1683
      cfun->machine->gp_save_offset = offset - total_size;
1684
    }
1685
  else
1686
    {
1687
      cfun->machine->gp_sp_offset = 0;
1688
      cfun->machine->gp_save_offset = 0;
1689
    }
1690
 
1691
  cfun->machine->fp_sp_offset = 0;
1692
  cfun->machine->fp_save_offset = 0;
1693
 
1694
  /* Ok, we're done.  */
1695
  return total_size;
1696
}
1697
 
1698
 
1699
/* We can always eliminate to the frame pointer.  We can eliminate to the
1700
   stack pointer unless a frame pointer is needed.  */
1701
 
1702
bool
1703
iq2000_can_eliminate (const int from, const int to)
1704
{
1705
  return (from == RETURN_ADDRESS_POINTER_REGNUM
1706
          && (! leaf_function_p ()
1707
              || (to == GP_REG_FIRST + 31 && leaf_function_p ())))
1708
          || (from != RETURN_ADDRESS_POINTER_REGNUM
1709
              && (to == HARD_FRAME_POINTER_REGNUM
1710
                  || (to == STACK_POINTER_REGNUM
1711
                      && ! frame_pointer_needed)));
1712
}
1713
 
1714
/* Implement INITIAL_ELIMINATION_OFFSET.  FROM is either the frame
1715
   pointer, argument pointer, or return address pointer.  TO is either
1716
   the stack pointer or hard frame pointer.  */
1717
 
1718
int
1719
iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1720
{
1721
  int offset;
1722
 
1723
  compute_frame_size (get_frame_size ());
1724
  if ((from) == FRAME_POINTER_REGNUM)
1725
    (offset) = 0;
1726
  else if ((from) == ARG_POINTER_REGNUM)
1727
    (offset) = (cfun->machine->total_size);
1728
  else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)
1729
    {
1730
      if (leaf_function_p ())
1731
        (offset) = 0;
1732
      else (offset) = cfun->machine->gp_sp_offset
1733
             + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT))
1734
                * (BYTES_BIG_ENDIAN != 0));
1735
    }
1736
  else
1737
    gcc_unreachable ();
1738
 
1739
  return offset;
1740
}
1741
 
1742
/* Common code to emit the insns (or to write the instructions to a file)
1743
   to save/restore registers.
1744
   Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg)
1745
   is not modified within save_restore_insns.  */
1746
 
1747
#define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0)
1748
 
1749
/* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM
1750
   and return an rtl expression for the register.  Write the assembly
1751
   instructions directly to FILE if it is not null, otherwise emit them as
1752
   rtl.
1753
 
1754
   This function is a subroutine of save_restore_insns.  It is used when
1755
   OFFSET is too large to add in a single instruction.  */
1756
 
1757
static rtx
1758
iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset)
1759
{
1760
  rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM);
1761
  rtx offset_rtx = GEN_INT (offset);
1762
 
1763
  emit_move_insn (reg, offset_rtx);
1764
  emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx));
1765
  return reg;
1766
}
1767
 
1768
/* Make INSN frame related and note that it performs the frame-related
1769
   operation DWARF_PATTERN.  */
1770
 
1771
static void
1772
iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
1773
{
1774
  RTX_FRAME_RELATED_P (insn) = 1;
1775
  REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
1776
                                      dwarf_pattern,
1777
                                      REG_NOTES (insn));
1778
}
1779
 
1780
/* Emit a move instruction that stores REG in MEM.  Make the instruction
1781
   frame related and note that it stores REG at (SP + OFFSET).  */
1782
 
1783
static void
1784
iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
1785
{
1786
  rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
1787
  rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
1788
 
1789
  iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
1790
                            gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
1791
}
1792
 
1793
/* Emit instructions to save/restore registers, as determined by STORE_P.  */
1794
 
1795
static void
1796
save_restore_insns (int store_p)
1797
{
1798
  long mask = cfun->machine->mask;
1799
  int regno;
1800
  rtx base_reg_rtx;
1801
  HOST_WIDE_INT base_offset;
1802
  HOST_WIDE_INT gp_offset;
1803
  HOST_WIDE_INT end_offset;
1804
 
1805
  gcc_assert (!frame_pointer_needed
1806
              || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST));
1807
 
1808
  if (mask == 0)
1809
    {
1810
      base_reg_rtx = 0, base_offset  = 0;
1811
      return;
1812
    }
1813
 
1814
  /* Save registers starting from high to low.  The debuggers prefer at least
1815
     the return register be stored at func+4, and also it allows us not to
1816
     need a nop in the epilog if at least one register is reloaded in
1817
     addition to return address.  */
1818
 
1819
  /* Save GP registers if needed.  */
1820
  /* Pick which pointer to use as a base register.  For small frames, just
1821
     use the stack pointer.  Otherwise, use a temporary register.  Save 2
1822
     cycles if the save area is near the end of a large frame, by reusing
1823
     the constant created in the prologue/epilogue to adjust the stack
1824
     frame.  */
1825
 
1826
  gp_offset = cfun->machine->gp_sp_offset;
1827
  end_offset
1828
    = gp_offset - (cfun->machine->gp_reg_size
1829
                   - GET_MODE_SIZE (gpr_mode));
1830
 
1831
  if (gp_offset < 0 || end_offset < 0)
1832
    internal_error
1833
      ("gp_offset (%ld) or end_offset (%ld) is less than zero",
1834
       (long) gp_offset, (long) end_offset);
1835
 
1836
  else if (gp_offset < 32768)
1837
    base_reg_rtx = stack_pointer_rtx, base_offset  = 0;
1838
  else
1839
    {
1840
      int regno;
1841
      int reg_save_count = 0;
1842
 
1843
      for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1844
        if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1;
1845
      base_offset = gp_offset - ((reg_save_count - 1) * 4);
1846
      base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset);
1847
    }
1848
 
1849
  for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
1850
    {
1851
      if (BITSET_P (mask, regno - GP_REG_FIRST))
1852
        {
1853
          rtx reg_rtx;
1854
          rtx mem_rtx
1855
            = gen_rtx_MEM (gpr_mode,
1856
                       gen_rtx_PLUS (Pmode, base_reg_rtx,
1857
                                GEN_INT (gp_offset - base_offset)));
1858
 
1859
          reg_rtx = gen_rtx_REG (gpr_mode, regno);
1860
 
1861
          if (store_p)
1862
            iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
1863
          else
1864
            {
1865
              emit_move_insn (reg_rtx, mem_rtx);
1866
            }
1867
          gp_offset -= GET_MODE_SIZE (gpr_mode);
1868
        }
1869
    }
1870
}
1871
 
1872
/* Expand the prologue into a bunch of separate insns.  */
1873
 
1874
void
1875
iq2000_expand_prologue (void)
1876
{
1877
  int regno;
1878
  HOST_WIDE_INT tsize;
1879
  int last_arg_is_vararg_marker = 0;
1880
  tree fndecl = current_function_decl;
1881
  tree fntype = TREE_TYPE (fndecl);
1882
  tree fnargs = DECL_ARGUMENTS (fndecl);
1883
  rtx next_arg_reg;
1884
  int i;
1885
  tree next_arg;
1886
  tree cur_arg;
1887
  CUMULATIVE_ARGS args_so_far_v;
1888
  cumulative_args_t args_so_far;
1889
  int store_args_on_stack = (iq2000_can_use_return_insn ());
1890
 
1891
  /* If struct value address is treated as the first argument.  */
1892
  if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
1893
      && !cfun->returns_pcc_struct
1894
      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
1895
    {
1896
      tree type = build_pointer_type (fntype);
1897
      tree function_result_decl = build_decl (BUILTINS_LOCATION,
1898
                                              PARM_DECL, NULL_TREE, type);
1899
 
1900
      DECL_ARG_TYPE (function_result_decl) = type;
1901
      DECL_CHAIN (function_result_decl) = fnargs;
1902
      fnargs = function_result_decl;
1903
    }
1904
 
1905
  /* For arguments passed in registers, find the register number
1906
     of the first argument in the variable part of the argument list,
1907
     otherwise GP_ARG_LAST+1.  Note also if the last argument is
1908
     the varargs special argument, and treat it as part of the
1909
     variable arguments.
1910
 
1911
     This is only needed if store_args_on_stack is true.  */
1912
  INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
1913
  args_so_far = pack_cumulative_args (&args_so_far_v);
1914
  regno = GP_ARG_FIRST;
1915
 
1916
  for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
1917
    {
1918
      tree passed_type = DECL_ARG_TYPE (cur_arg);
1919
      enum machine_mode passed_mode = TYPE_MODE (passed_type);
1920
      rtx entry_parm;
1921
 
1922
      if (TREE_ADDRESSABLE (passed_type))
1923
        {
1924
          passed_type = build_pointer_type (passed_type);
1925
          passed_mode = Pmode;
1926
        }
1927
 
1928
      entry_parm = iq2000_function_arg (args_so_far, passed_mode,
1929
                                        passed_type, true);
1930
 
1931
      iq2000_function_arg_advance (args_so_far, passed_mode,
1932
                                   passed_type, true);
1933
      next_arg = DECL_CHAIN (cur_arg);
1934
 
1935
      if (entry_parm && store_args_on_stack)
1936
        {
1937
          if (next_arg == 0
1938
              && DECL_NAME (cur_arg)
1939
              && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1940
                                "__builtin_va_alist"))
1941
                  || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)),
1942
                                   "va_alist"))))
1943
            {
1944
              last_arg_is_vararg_marker = 1;
1945
              break;
1946
            }
1947
          else
1948
            {
1949
              int words;
1950
 
1951
              gcc_assert (GET_CODE (entry_parm) == REG);
1952
 
1953
              /* Passed in a register, so will get homed automatically.  */
1954
              if (GET_MODE (entry_parm) == BLKmode)
1955
                words = (int_size_in_bytes (passed_type) + 3) / 4;
1956
              else
1957
                words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
1958
 
1959
              regno = REGNO (entry_parm) + words - 1;
1960
            }
1961
        }
1962
      else
1963
        {
1964
          regno = GP_ARG_LAST+1;
1965
          break;
1966
        }
1967
    }
1968
 
1969
  /* In order to pass small structures by value in registers we need to
1970
     shift the value into the high part of the register.
1971
     iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
1972
     adjustments to be made as the next_arg_reg variable, so we split up
1973
     the insns, and emit them separately.  */
1974
  next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
1975
                                      void_type_node, true);
1976
  if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
1977
    {
1978
      rtvec adjust = XVEC (next_arg_reg, 0);
1979
      int num = GET_NUM_ELEM (adjust);
1980
 
1981
      for (i = 0; i < num; i++)
1982
        {
1983
          rtx pattern;
1984
 
1985
          pattern = RTVEC_ELT (adjust, i);
1986
          if (GET_CODE (pattern) != SET
1987
              || GET_CODE (SET_SRC (pattern)) != ASHIFT)
1988
            abort_with_insn (pattern, "Insn is not a shift");
1989
          PUT_CODE (SET_SRC (pattern), ASHIFTRT);
1990
 
1991
          emit_insn (pattern);
1992
        }
1993
    }
1994
 
1995
  tsize = compute_frame_size (get_frame_size ());
1996
 
1997
  /* If this function is a varargs function, store any registers that
1998
     would normally hold arguments ($4 - $7) on the stack.  */
1999
  if (store_args_on_stack
2000
      && (stdarg_p (fntype)
2001
          || last_arg_is_vararg_marker))
2002
    {
2003
      int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD;
2004
      rtx ptr = stack_pointer_rtx;
2005
 
2006
      for (; regno <= GP_ARG_LAST; regno++)
2007
        {
2008
          if (offset != 0)
2009
            ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2010
          emit_move_insn (gen_rtx_MEM (gpr_mode, ptr),
2011
                          gen_rtx_REG (gpr_mode, regno));
2012
 
2013
          offset += GET_MODE_SIZE (gpr_mode);
2014
        }
2015
    }
2016
 
2017
  if (tsize > 0)
2018
    {
2019
      rtx tsize_rtx = GEN_INT (tsize);
2020
      rtx adjustment_rtx, insn, dwarf_pattern;
2021
 
2022
      if (tsize > 32767)
2023
        {
2024
          adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2025
          emit_move_insn (adjustment_rtx, tsize_rtx);
2026
        }
2027
      else
2028
        adjustment_rtx = tsize_rtx;
2029
 
2030
      insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2031
                                    adjustment_rtx));
2032
 
2033
      dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
2034
                                   plus_constant (stack_pointer_rtx, -tsize));
2035
 
2036
      iq2000_annotate_frame_insn (insn, dwarf_pattern);
2037
 
2038
      save_restore_insns (1);
2039
 
2040
      if (frame_pointer_needed)
2041
        {
2042
          rtx insn = 0;
2043
 
2044
          insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2045
                                       stack_pointer_rtx));
2046
 
2047
          if (insn)
2048
            RTX_FRAME_RELATED_P (insn) = 1;
2049
        }
2050
    }
2051
 
2052
  emit_insn (gen_blockage ());
2053
}
2054
 
2055
/* Expand the epilogue into a bunch of separate insns.  */
2056
 
2057
void
2058
iq2000_expand_epilogue (void)
2059
{
2060
  HOST_WIDE_INT tsize = cfun->machine->total_size;
2061
  rtx tsize_rtx = GEN_INT (tsize);
2062
  rtx tmp_rtx = (rtx)0;
2063
 
2064
  if (iq2000_can_use_return_insn ())
2065
    {
2066
      emit_jump_insn (gen_return ());
2067
      return;
2068
    }
2069
 
2070
  if (tsize > 32767)
2071
    {
2072
      tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM);
2073
      emit_move_insn (tmp_rtx, tsize_rtx);
2074
      tsize_rtx = tmp_rtx;
2075
    }
2076
 
2077
  if (tsize > 0)
2078
    {
2079
      if (frame_pointer_needed)
2080
        {
2081
          emit_insn (gen_blockage ());
2082
 
2083
          emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
2084
        }
2085
 
2086
      save_restore_insns (0);
2087
 
2088
      if (crtl->calls_eh_return)
2089
        {
2090
          rtx eh_ofs = EH_RETURN_STACKADJ_RTX;
2091
          emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx));
2092
          tsize_rtx = eh_ofs;
2093
        }
2094
 
2095
      emit_insn (gen_blockage ());
2096
 
2097
      if (tsize != 0 || crtl->calls_eh_return)
2098
        {
2099
          emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2100
                                 tsize_rtx));
2101
        }
2102
    }
2103
 
2104
  if (crtl->calls_eh_return)
2105
    {
2106
      /* Perform the additional bump for __throw.  */
2107
      emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
2108
                      stack_pointer_rtx);
2109
      emit_use (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM));
2110
      emit_jump_insn (gen_eh_return_internal ());
2111
    }
2112
  else
2113
      emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
2114
                                                  GP_REG_FIRST + 31)));
2115
}
2116
 
2117
void
2118
iq2000_expand_eh_return (rtx address)
2119
{
2120
  HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
2121
  rtx scratch;
2122
 
2123
  scratch = plus_constant (stack_pointer_rtx, gp_offset);
2124
  emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
2125
}
2126
 
2127
/* Return nonzero if this function is known to have a null epilogue.
2128
   This allows the optimizer to omit jumps to jumps if no stack
2129
   was created.  */
2130
 
2131
int
2132
iq2000_can_use_return_insn (void)
2133
{
2134
  if (! reload_completed)
2135
    return 0;
2136
 
2137
  if (df_regs_ever_live_p (31) || profile_flag)
2138
    return 0;
2139
 
2140
  if (cfun->machine->initialized)
2141
    return cfun->machine->total_size == 0;
2142
 
2143
  return compute_frame_size (get_frame_size ()) == 0;
2144
}
2145
 
2146
/* Choose the section to use for the constant rtx expression X that has
2147
   mode MODE.  */
2148
 
2149
static section *
2150
iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
2151
                           unsigned HOST_WIDE_INT align)
2152
{
2153
  /* For embedded applications, always put constants in read-only data,
2154
     in order to reduce RAM usage.  */
2155
  return mergeable_constant_section (mode, align, 0);
2156
}
2157
 
2158
/* Choose the section to use for DECL.  RELOC is true if its value contains
2159
   any relocatable expression.
2160
 
2161
   Some of the logic used here needs to be replicated in
2162
   ENCODE_SECTION_INFO in iq2000.h so that references to these symbols
2163
   are done correctly.  */
2164
 
2165
static section *
2166
iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED,
2167
                       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
2168
{
2169
  if (TARGET_EMBEDDED_DATA)
2170
    {
2171
      /* For embedded applications, always put an object in read-only data
2172
         if possible, in order to reduce RAM usage.  */
2173
      if ((TREE_CODE (decl) == VAR_DECL
2174
           && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2175
           && DECL_INITIAL (decl)
2176
           && (DECL_INITIAL (decl) == error_mark_node
2177
               || TREE_CONSTANT (DECL_INITIAL (decl))))
2178
          /* Deal with calls from output_constant_def_contents.  */
2179
          || TREE_CODE (decl) != VAR_DECL)
2180
        return readonly_data_section;
2181
      else
2182
        return data_section;
2183
    }
2184
  else
2185
    {
2186
      /* For hosted applications, always put an object in small data if
2187
         possible, as this gives the best performance.  */
2188
      if ((TREE_CODE (decl) == VAR_DECL
2189
           && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl)
2190
           && DECL_INITIAL (decl)
2191
           && (DECL_INITIAL (decl) == error_mark_node
2192
               || TREE_CONSTANT (DECL_INITIAL (decl))))
2193
          /* Deal with calls from output_constant_def_contents.  */
2194
          || TREE_CODE (decl) != VAR_DECL)
2195
        return readonly_data_section;
2196
      else
2197
        return data_section;
2198
    }
2199
}
2200
/* Return register to use for a function return value with VALTYPE for function
2201
   FUNC.  */
2202
 
2203
static rtx
2204
iq2000_function_value (const_tree valtype,
2205
                       const_tree fn_decl_or_type,
2206
                       bool outgoing ATTRIBUTE_UNUSED)
2207
{
2208
  int reg = GP_RETURN;
2209
  enum machine_mode mode = TYPE_MODE (valtype);
2210
  int unsignedp = TYPE_UNSIGNED (valtype);
2211
  const_tree func = fn_decl_or_type;
2212
 
2213
  if (fn_decl_or_type
2214
      && !DECL_P (fn_decl_or_type))
2215
    fn_decl_or_type = NULL;
2216
 
2217
  /* Since we promote return types, we must promote the mode here too.  */
2218
  mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
2219
 
2220
  return gen_rtx_REG (mode, reg);
2221
}
2222
 
2223
/* Worker function for TARGET_LIBCALL_VALUE.  */
2224
 
2225
static rtx
2226
iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2227
{
2228
  return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
2229
                        || GET_MODE_SIZE (mode) >= 4)
2230
                       ? mode : SImode),
2231
                      GP_RETURN);
2232
}
2233
 
2234
/* Worker function for FUNCTION_VALUE_REGNO_P.
2235
 
2236
   On the IQ2000, R2 and R3 are the only register thus used.  */
2237
 
2238
bool
2239
iq2000_function_value_regno_p (const unsigned int regno)
2240
{
2241
  return (regno == GP_RETURN);
2242
}
2243
 
2244
 
2245
/* Return true when an argument must be passed by reference.  */
2246
 
2247
static bool
2248
iq2000_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode,
2249
                          const_tree type, bool named ATTRIBUTE_UNUSED)
2250
{
2251
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2252
  int size;
2253
 
2254
  /* We must pass by reference if we would be both passing in registers
2255
     and the stack.  This is because any subsequent partial arg would be
2256
     handled incorrectly in this case.  */
2257
  if (cum && targetm.calls.must_pass_in_stack (mode, type))
2258
     {
2259
       /* Don't pass the actual CUM to FUNCTION_ARG, because we would
2260
          get double copies of any offsets generated for small structs
2261
          passed in registers.  */
2262
       CUMULATIVE_ARGS temp;
2263
 
2264
       temp = *cum;
2265
       if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
2266
           != 0)
2267
         return 1;
2268
     }
2269
 
2270
  if (type == NULL_TREE || mode == DImode || mode == DFmode)
2271
    return 0;
2272
 
2273
  size = int_size_in_bytes (type);
2274
  return size == -1 || size > UNITS_PER_WORD;
2275
}
2276
 
2277
/* Return the length of INSN.  LENGTH is the initial length computed by
2278
   attributes in the machine-description file.  */
2279
 
2280
int
2281
iq2000_adjust_insn_length (rtx insn, int length)
2282
{
2283
  /* A unconditional jump has an unfilled delay slot if it is not part
2284
     of a sequence.  A conditional jump normally has a delay slot.  */
2285
  if (simplejump_p (insn)
2286
      || (   (GET_CODE (insn) == JUMP_INSN
2287
           || GET_CODE (insn) == CALL_INSN)))
2288
    length += 4;
2289
 
2290
  return length;
2291
}
2292
 
2293
/* Output assembly instructions to perform a conditional branch.
2294
 
2295
   INSN is the branch instruction.  OPERANDS[0] is the condition.
2296
   OPERANDS[1] is the target of the branch.  OPERANDS[2] is the target
2297
   of the first operand to the condition.  If TWO_OPERANDS_P is
2298
   nonzero the comparison takes two operands; OPERANDS[3] will be the
2299
   second operand.
2300
 
2301
   If INVERTED_P is nonzero we are to branch if the condition does
2302
   not hold.  If FLOAT_P is nonzero this is a floating-point comparison.
2303
 
2304
   LENGTH is the length (in bytes) of the sequence we are to generate.
2305
   That tells us whether to generate a simple conditional branch, or a
2306
   reversed conditional branch around a `jr' instruction.  */
2307
 
2308
char *
2309
iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
2310
                                  int float_p, int inverted_p, int length)
2311
{
2312
  static char buffer[200];
2313
  /* The kind of comparison we are doing.  */
2314
  enum rtx_code code = GET_CODE (operands[0]);
2315
  /* Nonzero if the opcode for the comparison needs a `z' indicating
2316
     that it is a comparison against zero.  */
2317
  int need_z_p;
2318
  /* A string to use in the assembly output to represent the first
2319
     operand.  */
2320
  const char *op1 = "%z2";
2321
  /* A string to use in the assembly output to represent the second
2322
     operand.  Use the hard-wired zero register if there's no second
2323
     operand.  */
2324
  const char *op2 = (two_operands_p ? ",%z3" : ",%.");
2325
  /* The operand-printing string for the comparison.  */
2326
  const char *comp = (float_p ? "%F0" : "%C0");
2327
  /* The operand-printing string for the inverted comparison.  */
2328
  const char *inverted_comp = (float_p ? "%W0" : "%N0");
2329
 
2330
  /* Likely variants of each branch instruction annul the instruction
2331
     in the delay slot if the branch is not taken.  */
2332
  iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2333
 
2334
  if (!two_operands_p)
2335
    {
2336
      /* To compute whether than A > B, for example, we normally
2337
         subtract B from A and then look at the sign bit.  But, if we
2338
         are doing an unsigned comparison, and B is zero, we don't
2339
         have to do the subtraction.  Instead, we can just check to
2340
         see if A is nonzero.  Thus, we change the CODE here to
2341
         reflect the simpler comparison operation.  */
2342
      switch (code)
2343
        {
2344
        case GTU:
2345
          code = NE;
2346
          break;
2347
 
2348
        case LEU:
2349
          code = EQ;
2350
          break;
2351
 
2352
        case GEU:
2353
          /* A condition which will always be true.  */
2354
          code = EQ;
2355
          op1 = "%.";
2356
          break;
2357
 
2358
        case LTU:
2359
          /* A condition which will always be false.  */
2360
          code = NE;
2361
          op1 = "%.";
2362
          break;
2363
 
2364
        default:
2365
          /* Not a special case.  */
2366
          break;
2367
        }
2368
    }
2369
 
2370
  /* Relative comparisons are always done against zero.  But
2371
     equality comparisons are done between two operands, and therefore
2372
     do not require a `z' in the assembly language output.  */
2373
  need_z_p = (!float_p && code != EQ && code != NE);
2374
  /* For comparisons against zero, the zero is not provided
2375
     explicitly.  */
2376
  if (need_z_p)
2377
    op2 = "";
2378
 
2379
  /* Begin by terminating the buffer.  That way we can always use
2380
     strcat to add to it.  */
2381
  buffer[0] = '\0';
2382
 
2383
  switch (length)
2384
    {
2385
    case 4:
2386
    case 8:
2387
      /* Just a simple conditional branch.  */
2388
      if (float_p)
2389
        sprintf (buffer, "b%s%%?\t%%Z2%%1",
2390
                 inverted_p ? inverted_comp : comp);
2391
      else
2392
        sprintf (buffer, "b%s%s%%?\t%s%s,%%1",
2393
                 inverted_p ? inverted_comp : comp,
2394
                 need_z_p ? "z" : "",
2395
                 op1,
2396
                 op2);
2397
      return buffer;
2398
 
2399
    case 12:
2400
    case 16:
2401
      {
2402
        /* Generate a reversed conditional branch around ` j'
2403
           instruction:
2404
 
2405
                .set noreorder
2406
                .set nomacro
2407
                bc    l
2408
                nop
2409
                j     target
2410
                .set macro
2411
                .set reorder
2412
             l:
2413
 
2414
           Because we have to jump four bytes *past* the following
2415
           instruction if this branch was annulled, we can't just use
2416
           a label, as in the picture above; there's no way to put the
2417
           label after the next instruction, as the assembler does not
2418
           accept `.L+4' as the target of a branch.  (We can't just
2419
           wait until the next instruction is output; it might be a
2420
           macro and take up more than four bytes.  Once again, we see
2421
           why we want to eliminate macros.)
2422
 
2423
           If the branch is annulled, we jump four more bytes that we
2424
           would otherwise; that way we skip the annulled instruction
2425
           in the delay slot.  */
2426
 
2427
        const char *target
2428
          = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12");
2429
        char *c;
2430
 
2431
        c = strchr (buffer, '\0');
2432
        /* Generate the reversed comparison.  This takes four
2433
           bytes.  */
2434
        if (float_p)
2435
          sprintf (c, "b%s\t%%Z2%s",
2436
                   inverted_p ? comp : inverted_comp,
2437
                   target);
2438
        else
2439
          sprintf (c, "b%s%s\t%s%s,%s",
2440
                   inverted_p ? comp : inverted_comp,
2441
                   need_z_p ? "z" : "",
2442
                   op1,
2443
                   op2,
2444
                   target);
2445
        strcat (c, "\n\tnop\n\tj\t%1");
2446
        if (length == 16)
2447
          /* The delay slot was unfilled.  Since we're inside
2448
             .noreorder, the assembler will not fill in the NOP for
2449
             us, so we must do it ourselves.  */
2450
          strcat (buffer, "\n\tnop");
2451
        return buffer;
2452
      }
2453
 
2454
    default:
2455
      gcc_unreachable ();
2456
    }
2457
 
2458
  /* NOTREACHED */
2459
  return 0;
2460
}
2461
 
2462
#define def_builtin(NAME, TYPE, CODE)                                   \
2463
  add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,    \
2464
                       NULL, NULL_TREE)
2465
 
2466
static void
2467
iq2000_init_builtins (void)
2468
{
2469
  tree void_ftype, void_ftype_int, void_ftype_int_int;
2470
  tree void_ftype_int_int_int;
2471
  tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
2472
  tree int_ftype_int_int_int_int;
2473
 
2474
  /* func () */
2475
  void_ftype
2476
    = build_function_type_list (void_type_node, NULL_TREE);
2477
 
2478
  /* func (int) */
2479
  void_ftype_int
2480
    = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
2481
 
2482
  /* void func (int, int) */
2483
  void_ftype_int_int
2484
    = build_function_type_list (void_type_node,
2485
                                integer_type_node,
2486
                                integer_type_node,
2487
                                NULL_TREE);
2488
 
2489
  /* int func (int) */
2490
  int_ftype_int
2491
    = build_function_type_list (integer_type_node,
2492
                                integer_type_node, NULL_TREE);
2493
 
2494
  /* int func (int, int) */
2495
  int_ftype_int_int
2496
    = build_function_type_list (integer_type_node,
2497
                                integer_type_node,
2498
                                integer_type_node,
2499
                                NULL_TREE);
2500
 
2501
  /* void func (int, int, int) */
2502
  void_ftype_int_int_int
2503
    = build_function_type_list (void_type_node,
2504
                                integer_type_node,
2505
                                integer_type_node,
2506
                                integer_type_node,
2507
                                NULL_TREE);
2508
 
2509
  /* int func (int, int, int) */
2510
  int_ftype_int_int_int
2511
    = build_function_type_list (integer_type_node,
2512
                                integer_type_node,
2513
                                integer_type_node,
2514
                                integer_type_node,
2515
                                NULL_TREE);
2516
 
2517
  /* int func (int, int, int, int) */
2518
  int_ftype_int_int_int_int
2519
    = build_function_type_list (integer_type_node,
2520
                                integer_type_node,
2521
                                integer_type_node,
2522
                                integer_type_node,
2523
                                integer_type_node,
2524
                                NULL_TREE);
2525
 
2526
  def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
2527
  def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
2528
  def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR);
2529
  def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL);
2530
  def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0);
2531
  def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1);
2532
  def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2);
2533
  def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3);
2534
  def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0);
2535
  def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1);
2536
  def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2);
2537
  def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3);
2538
  def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0);
2539
  def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1);
2540
  def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2);
2541
  def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3);
2542
  def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0);
2543
  def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1);
2544
  def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2);
2545
  def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3);
2546
  def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR);
2547
  def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB);
2548
  def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX);
2549
  def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD);
2550
  def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR);
2551
  def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB);
2552
  def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX);
2553
  def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L);
2554
  def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64);
2555
  def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L);
2556
  def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK);
2557
  def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK);
2558
  def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32);
2559
  def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L);
2560
  def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64);
2561
  def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L);
2562
  def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL);
2563
  def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB);
2564
  def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL);
2565
  def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK);
2566
  def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU);
2567
  def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL);
2568
  def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE);
2569
  def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL);
2570
  def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU);
2571
  def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL);
2572
}
2573
 
2574
/* Builtin for ICODE having ARGCOUNT args in EXP where each arg
2575
   has an rtx CODE.  */
2576
 
2577
static rtx
2578
expand_one_builtin (enum insn_code icode, rtx target, tree exp,
2579
                    enum rtx_code *code, int argcount)
2580
{
2581
  rtx pat;
2582
  tree arg [5];
2583
  rtx op [5];
2584
  enum machine_mode mode [5];
2585
  int i;
2586
 
2587
  mode[0] = insn_data[icode].operand[0].mode;
2588
  for (i = 0; i < argcount; i++)
2589
    {
2590
      arg[i] = CALL_EXPR_ARG (exp, i);
2591
      op[i] = expand_normal (arg[i]);
2592
      mode[i] = insn_data[icode].operand[i].mode;
2593
      if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT)
2594
        error ("argument %qd is not a constant", i + 1);
2595
      if (code[i] == REG
2596
          && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i]))
2597
        op[i] = copy_to_mode_reg (mode[i], op[i]);
2598
    }
2599
 
2600
  if (insn_data[icode].operand[0].constraint[0] == '=')
2601
    {
2602
      if (target == 0
2603
          || GET_MODE (target) != mode[0]
2604
          || ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
2605
        target = gen_reg_rtx (mode[0]);
2606
    }
2607
  else
2608
    target = 0;
2609
 
2610
  switch (argcount)
2611
    {
2612
    case 0:
2613
        pat = GEN_FCN (icode) (target);
2614
    case 1:
2615
      if (target)
2616
        pat = GEN_FCN (icode) (target, op[0]);
2617
      else
2618
        pat = GEN_FCN (icode) (op[0]);
2619
      break;
2620
    case 2:
2621
      if (target)
2622
        pat = GEN_FCN (icode) (target, op[0], op[1]);
2623
      else
2624
        pat = GEN_FCN (icode) (op[0], op[1]);
2625
      break;
2626
    case 3:
2627
      if (target)
2628
        pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2629
      else
2630
        pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2631
      break;
2632
    case 4:
2633
      if (target)
2634
        pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2635
      else
2636
        pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2637
      break;
2638
    default:
2639
      gcc_unreachable ();
2640
    }
2641
 
2642
  if (! pat)
2643
    return 0;
2644
  emit_insn (pat);
2645
  return target;
2646
}
2647
 
2648
/* Expand an expression EXP that calls a built-in function,
2649
   with result going to TARGET if that's convenient
2650
   (and in mode MODE if that's convenient).
2651
   SUBTARGET may be used as the target for computing one of EXP's operands.
2652
   IGNORE is nonzero if the value is to be ignored.  */
2653
 
2654
static rtx
2655
iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2656
                       enum machine_mode mode ATTRIBUTE_UNUSED,
2657
                       int ignore ATTRIBUTE_UNUSED)
2658
{
2659
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2660
  int fcode = DECL_FUNCTION_CODE (fndecl);
2661
  enum rtx_code code [5];
2662
 
2663
  code[0] = REG;
2664
  code[1] = REG;
2665
  code[2] = REG;
2666
  code[3] = REG;
2667
  code[4] = REG;
2668
  switch (fcode)
2669
    {
2670
    default:
2671
      break;
2672
 
2673
    case IQ2000_BUILTIN_ADO16:
2674
      return expand_one_builtin (CODE_FOR_ado16, target, exp, code, 2);
2675
 
2676
    case IQ2000_BUILTIN_RAM:
2677
      code[1] = CONST_INT;
2678
      code[2] = CONST_INT;
2679
      code[3] = CONST_INT;
2680
      return expand_one_builtin (CODE_FOR_ram, target, exp, code, 4);
2681
 
2682
    case IQ2000_BUILTIN_CHKHDR:
2683
      return expand_one_builtin (CODE_FOR_chkhdr, target, exp, code, 2);
2684
 
2685
    case IQ2000_BUILTIN_PKRL:
2686
      return expand_one_builtin (CODE_FOR_pkrl, target, exp, code, 2);
2687
 
2688
    case IQ2000_BUILTIN_CFC0:
2689
      code[0] = CONST_INT;
2690
      return expand_one_builtin (CODE_FOR_cfc0, target, exp, code, 1);
2691
 
2692
    case IQ2000_BUILTIN_CFC1:
2693
      code[0] = CONST_INT;
2694
      return expand_one_builtin (CODE_FOR_cfc1, target, exp, code, 1);
2695
 
2696
    case IQ2000_BUILTIN_CFC2:
2697
      code[0] = CONST_INT;
2698
      return expand_one_builtin (CODE_FOR_cfc2, target, exp, code, 1);
2699
 
2700
    case IQ2000_BUILTIN_CFC3:
2701
      code[0] = CONST_INT;
2702
      return expand_one_builtin (CODE_FOR_cfc3, target, exp, code, 1);
2703
 
2704
    case IQ2000_BUILTIN_CTC0:
2705
      code[1] = CONST_INT;
2706
      return expand_one_builtin (CODE_FOR_ctc0, target, exp, code, 2);
2707
 
2708
    case IQ2000_BUILTIN_CTC1:
2709
      code[1] = CONST_INT;
2710
      return expand_one_builtin (CODE_FOR_ctc1, target, exp, code, 2);
2711
 
2712
    case IQ2000_BUILTIN_CTC2:
2713
      code[1] = CONST_INT;
2714
      return expand_one_builtin (CODE_FOR_ctc2, target, exp, code, 2);
2715
 
2716
    case IQ2000_BUILTIN_CTC3:
2717
      code[1] = CONST_INT;
2718
      return expand_one_builtin (CODE_FOR_ctc3, target, exp, code, 2);
2719
 
2720
    case IQ2000_BUILTIN_MFC0:
2721
      code[0] = CONST_INT;
2722
      return expand_one_builtin (CODE_FOR_mfc0, target, exp, code, 1);
2723
 
2724
    case IQ2000_BUILTIN_MFC1:
2725
      code[0] = CONST_INT;
2726
      return expand_one_builtin (CODE_FOR_mfc1, target, exp, code, 1);
2727
 
2728
    case IQ2000_BUILTIN_MFC2:
2729
      code[0] = CONST_INT;
2730
      return expand_one_builtin (CODE_FOR_mfc2, target, exp, code, 1);
2731
 
2732
    case IQ2000_BUILTIN_MFC3:
2733
      code[0] = CONST_INT;
2734
      return expand_one_builtin (CODE_FOR_mfc3, target, exp, code, 1);
2735
 
2736
    case IQ2000_BUILTIN_MTC0:
2737
      code[1] = CONST_INT;
2738
      return expand_one_builtin (CODE_FOR_mtc0, target, exp, code, 2);
2739
 
2740
    case IQ2000_BUILTIN_MTC1:
2741
      code[1] = CONST_INT;
2742
      return expand_one_builtin (CODE_FOR_mtc1, target, exp, code, 2);
2743
 
2744
    case IQ2000_BUILTIN_MTC2:
2745
      code[1] = CONST_INT;
2746
      return expand_one_builtin (CODE_FOR_mtc2, target, exp, code, 2);
2747
 
2748
    case IQ2000_BUILTIN_MTC3:
2749
      code[1] = CONST_INT;
2750
      return expand_one_builtin (CODE_FOR_mtc3, target, exp, code, 2);
2751
 
2752
    case IQ2000_BUILTIN_LUR:
2753
      return expand_one_builtin (CODE_FOR_lur, target, exp, code, 2);
2754
 
2755
    case IQ2000_BUILTIN_RB:
2756
      return expand_one_builtin (CODE_FOR_rb, target, exp, code, 2);
2757
 
2758
    case IQ2000_BUILTIN_RX:
2759
      return expand_one_builtin (CODE_FOR_rx, target, exp, code, 2);
2760
 
2761
    case IQ2000_BUILTIN_SRRD:
2762
      return expand_one_builtin (CODE_FOR_srrd, target, exp, code, 1);
2763
 
2764
    case IQ2000_BUILTIN_SRWR:
2765
      return expand_one_builtin (CODE_FOR_srwr, target, exp, code, 2);
2766
 
2767
    case IQ2000_BUILTIN_WB:
2768
      return expand_one_builtin (CODE_FOR_wb, target, exp, code, 2);
2769
 
2770
    case IQ2000_BUILTIN_WX:
2771
      return expand_one_builtin (CODE_FOR_wx, target, exp, code, 2);
2772
 
2773
    case IQ2000_BUILTIN_LUC32L:
2774
      return expand_one_builtin (CODE_FOR_luc32l, target, exp, code, 2);
2775
 
2776
    case IQ2000_BUILTIN_LUC64:
2777
      return expand_one_builtin (CODE_FOR_luc64, target, exp, code, 2);
2778
 
2779
    case IQ2000_BUILTIN_LUC64L:
2780
      return expand_one_builtin (CODE_FOR_luc64l, target, exp, code, 2);
2781
 
2782
    case IQ2000_BUILTIN_LUK:
2783
      return expand_one_builtin (CODE_FOR_luk, target, exp, code, 2);
2784
 
2785
    case IQ2000_BUILTIN_LULCK:
2786
      return expand_one_builtin (CODE_FOR_lulck, target, exp, code, 1);
2787
 
2788
    case IQ2000_BUILTIN_LUM32:
2789
      return expand_one_builtin (CODE_FOR_lum32, target, exp, code, 2);
2790
 
2791
    case IQ2000_BUILTIN_LUM32L:
2792
      return expand_one_builtin (CODE_FOR_lum32l, target, exp, code, 2);
2793
 
2794
    case IQ2000_BUILTIN_LUM64:
2795
      return expand_one_builtin (CODE_FOR_lum64, target, exp, code, 2);
2796
 
2797
    case IQ2000_BUILTIN_LUM64L:
2798
      return expand_one_builtin (CODE_FOR_lum64l, target, exp, code, 2);
2799
 
2800
    case IQ2000_BUILTIN_LURL:
2801
      return expand_one_builtin (CODE_FOR_lurl, target, exp, code, 2);
2802
 
2803
    case IQ2000_BUILTIN_MRGB:
2804
      code[2] = CONST_INT;
2805
      return expand_one_builtin (CODE_FOR_mrgb, target, exp, code, 3);
2806
 
2807
    case IQ2000_BUILTIN_SRRDL:
2808
      return expand_one_builtin (CODE_FOR_srrdl, target, exp, code, 1);
2809
 
2810
    case IQ2000_BUILTIN_SRULCK:
2811
      return expand_one_builtin (CODE_FOR_srulck, target, exp, code, 1);
2812
 
2813
    case IQ2000_BUILTIN_SRWRU:
2814
      return expand_one_builtin (CODE_FOR_srwru, target, exp, code, 2);
2815
 
2816
    case IQ2000_BUILTIN_TRAPQFL:
2817
      return expand_one_builtin (CODE_FOR_trapqfl, target, exp, code, 0);
2818
 
2819
    case IQ2000_BUILTIN_TRAPQNE:
2820
      return expand_one_builtin (CODE_FOR_trapqne, target, exp, code, 0);
2821
 
2822
    case IQ2000_BUILTIN_TRAPREL:
2823
      return expand_one_builtin (CODE_FOR_traprel, target, exp, code, 1);
2824
 
2825
    case IQ2000_BUILTIN_WBU:
2826
      return expand_one_builtin (CODE_FOR_wbu, target, exp, code, 3);
2827
 
2828
    case IQ2000_BUILTIN_SYSCALL:
2829
      return expand_one_builtin (CODE_FOR_syscall, target, exp, code, 0);
2830
    }
2831
 
2832
  return NULL_RTX;
2833
}
2834
 
2835
/* Worker function for TARGET_RETURN_IN_MEMORY.  */
2836
 
2837
static bool
2838
iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2839
{
2840
  return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2841
          || (int_size_in_bytes (type) == -1));
2842
}
2843
 
2844
/* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
2845
 
2846
static void
2847
iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
2848
                               enum machine_mode mode ATTRIBUTE_UNUSED,
2849
                               tree type ATTRIBUTE_UNUSED, int * pretend_size,
2850
                               int no_rtl)
2851
{
2852
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2853
  unsigned int iq2000_off = ! cum->last_arg_fp;
2854
  unsigned int iq2000_fp_off = cum->last_arg_fp;
2855
 
2856
  if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off))
2857
    {
2858
      int iq2000_save_gp_regs
2859
        = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off;
2860
      int iq2000_save_fp_regs
2861
        = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off);
2862
 
2863
      if (iq2000_save_gp_regs < 0)
2864
        iq2000_save_gp_regs = 0;
2865
      if (iq2000_save_fp_regs < 0)
2866
        iq2000_save_fp_regs = 0;
2867
 
2868
      *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD)
2869
                      + (iq2000_save_fp_regs * UNITS_PER_FPREG));
2870
 
2871
      if (! (no_rtl))
2872
        {
2873
          if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)
2874
            {
2875
              rtx ptr, mem;
2876
              ptr = plus_constant (virtual_incoming_args_rtx,
2877
                                   - (iq2000_save_gp_regs
2878
                                      * UNITS_PER_WORD));
2879
              mem = gen_rtx_MEM (BLKmode, ptr);
2880
              move_block_from_reg
2881
                (cum->arg_words + GP_ARG_FIRST + iq2000_off,
2882
                 mem,
2883
                 iq2000_save_gp_regs);
2884
            }
2885
        }
2886
    }
2887
}
2888
 
2889
/* A C compound statement to output to stdio stream STREAM the
2890
   assembler syntax for an instruction operand that is a memory
2891
   reference whose address is ADDR.  ADDR is an RTL expression.  */
2892
 
2893
static void
2894
iq2000_print_operand_address (FILE * file, rtx addr)
2895
{
2896
  if (!addr)
2897
    error ("PRINT_OPERAND_ADDRESS, null pointer");
2898
 
2899
  else
2900
    switch (GET_CODE (addr))
2901
      {
2902
      case REG:
2903
        if (REGNO (addr) == ARG_POINTER_REGNUM)
2904
          abort_with_insn (addr, "Arg pointer not eliminated.");
2905
 
2906
        fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
2907
        break;
2908
 
2909
      case LO_SUM:
2910
        {
2911
          rtx arg0 = XEXP (addr, 0);
2912
          rtx arg1 = XEXP (addr, 1);
2913
 
2914
          if (GET_CODE (arg0) != REG)
2915
            abort_with_insn (addr,
2916
                             "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
2917
 
2918
          fprintf (file, "%%lo(");
2919
          iq2000_print_operand_address (file, arg1);
2920
          fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
2921
        }
2922
        break;
2923
 
2924
      case PLUS:
2925
        {
2926
          rtx reg = 0;
2927
          rtx offset = 0;
2928
          rtx arg0 = XEXP (addr, 0);
2929
          rtx arg1 = XEXP (addr, 1);
2930
 
2931
          if (GET_CODE (arg0) == REG)
2932
            {
2933
              reg = arg0;
2934
              offset = arg1;
2935
              if (GET_CODE (offset) == REG)
2936
                abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
2937
            }
2938
 
2939
          else if (GET_CODE (arg1) == REG)
2940
              reg = arg1, offset = arg0;
2941
          else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
2942
            {
2943
              output_addr_const (file, addr);
2944
              break;
2945
            }
2946
          else
2947
            abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
2948
 
2949
          if (! CONSTANT_P (offset))
2950
            abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2");
2951
 
2952
          if (REGNO (reg) == ARG_POINTER_REGNUM)
2953
            abort_with_insn (addr, "Arg pointer not eliminated.");
2954
 
2955
          output_addr_const (file, offset);
2956
          fprintf (file, "(%s)", reg_names [REGNO (reg)]);
2957
        }
2958
        break;
2959
 
2960
      case LABEL_REF:
2961
      case SYMBOL_REF:
2962
      case CONST_INT:
2963
      case CONST:
2964
        output_addr_const (file, addr);
2965
        if (GET_CODE (addr) == CONST_INT)
2966
          fprintf (file, "(%s)", reg_names [0]);
2967
        break;
2968
 
2969
      default:
2970
        abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1");
2971
        break;
2972
    }
2973
}
2974
 
2975
/* A C compound statement to output to stdio stream FILE the
2976
   assembler syntax for an instruction operand OP.
2977
 
2978
   LETTER is a value that can be used to specify one of several ways
2979
   of printing the operand.  It is used when identical operands
2980
   must be printed differently depending on the context.  LETTER
2981
   comes from the `%' specification that was used to request
2982
   printing of the operand.  If the specification was just `%DIGIT'
2983
   then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER
2984
   is the ASCII code for LTR.
2985
 
2986
   If OP is a register, this macro should print the register's name.
2987
   The names can be found in an array `reg_names' whose type is
2988
   `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.
2989
 
2990
   When the machine description has a specification `%PUNCT' (a `%'
2991
   followed by a punctuation character), this macro is called with
2992
   a null pointer for X and the punctuation character for LETTER.
2993
 
2994
   The IQ2000 specific codes are:
2995
 
2996
   'X'  X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x",
2997
   'x'  X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x",
2998
   'd'  output integer constant in decimal,
2999
   'z'  if the operand is 0, use $0 instead of normal operand.
3000
   'D'  print second part of double-word register or memory operand.
3001
   'L'  print low-order register of double-word register operand.
3002
   'M'  print high-order register of double-word register operand.
3003
   'C'  print part of opcode for a branch condition.
3004
   'F'  print part of opcode for a floating-point branch condition.
3005
   'N'  print part of opcode for a branch condition, inverted.
3006
   'W'  print part of opcode for a floating-point branch condition, inverted.
3007
   'A'  Print part of opcode for a bit test condition.
3008
   'P'  Print label for a bit test.
3009
   'p'  Print log for a bit test.
3010
   'B'  print 'z' for EQ, 'n' for NE
3011
   'b'  print 'n' for EQ, 'z' for NE
3012
   'T'  print 'f' for EQ, 't' for NE
3013
   't'  print 't' for EQ, 'f' for NE
3014
   'Z'  print register and a comma, but print nothing for $fcc0
3015
   '?'  Print 'l' if we are to use a branch likely instead of normal branch.
3016
   '@'  Print the name of the assembler temporary register (at or $1).
3017
   '.'  Print the name of the register with a hard-wired zero (zero or $0).
3018
   '$'  Print the name of the stack pointer register (sp or $29).
3019
   '+'  Print the name of the gp register (gp or $28).  */
3020
 
3021
static void
3022
iq2000_print_operand (FILE *file, rtx op, int letter)
3023
{
3024
  enum rtx_code code;
3025
 
3026
  if (iq2000_print_operand_punct_valid_p (letter))
3027
    {
3028
      switch (letter)
3029
        {
3030
        case '?':
3031
          if (iq2000_branch_likely)
3032
            putc ('l', file);
3033
          break;
3034
 
3035
        case '@':
3036
          fputs (reg_names [GP_REG_FIRST + 1], file);
3037
          break;
3038
 
3039
        case '.':
3040
          fputs (reg_names [GP_REG_FIRST + 0], file);
3041
          break;
3042
 
3043
        case '$':
3044
          fputs (reg_names[STACK_POINTER_REGNUM], file);
3045
          break;
3046
 
3047
        case '+':
3048
          fputs (reg_names[GP_REG_FIRST + 28], file);
3049
          break;
3050
 
3051
        default:
3052
          error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3053
          break;
3054
        }
3055
 
3056
      return;
3057
    }
3058
 
3059
  if (! op)
3060
    {
3061
      error ("PRINT_OPERAND null pointer");
3062
      return;
3063
    }
3064
 
3065
  code = GET_CODE (op);
3066
 
3067
  if (code == SIGN_EXTEND)
3068
    op = XEXP (op, 0), code = GET_CODE (op);
3069
 
3070
  if (letter == 'C')
3071
    switch (code)
3072
      {
3073
      case EQ:  fputs ("eq",  file); break;
3074
      case NE:  fputs ("ne",  file); break;
3075
      case GT:  fputs ("gt",  file); break;
3076
      case GE:  fputs ("ge",  file); break;
3077
      case LT:  fputs ("lt",  file); break;
3078
      case LE:  fputs ("le",  file); break;
3079
      case GTU: fputs ("ne", file); break;
3080
      case GEU: fputs ("geu", file); break;
3081
      case LTU: fputs ("ltu", file); break;
3082
      case LEU: fputs ("eq", file); break;
3083
      default:
3084
        abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C");
3085
      }
3086
 
3087
  else if (letter == 'N')
3088
    switch (code)
3089
      {
3090
      case EQ:  fputs ("ne",  file); break;
3091
      case NE:  fputs ("eq",  file); break;
3092
      case GT:  fputs ("le",  file); break;
3093
      case GE:  fputs ("lt",  file); break;
3094
      case LT:  fputs ("ge",  file); break;
3095
      case LE:  fputs ("gt",  file); break;
3096
      case GTU: fputs ("leu", file); break;
3097
      case GEU: fputs ("ltu", file); break;
3098
      case LTU: fputs ("geu", file); break;
3099
      case LEU: fputs ("gtu", file); break;
3100
      default:
3101
        abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N");
3102
      }
3103
 
3104
  else if (letter == 'F')
3105
    switch (code)
3106
      {
3107
      case EQ: fputs ("c1f", file); break;
3108
      case NE: fputs ("c1t", file); break;
3109
      default:
3110
        abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F");
3111
      }
3112
 
3113
  else if (letter == 'W')
3114
    switch (code)
3115
      {
3116
      case EQ: fputs ("c1t", file); break;
3117
      case NE: fputs ("c1f", file); break;
3118
      default:
3119
        abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
3120
      }
3121
 
3122
  else if (letter == 'A')
3123
    fputs (code == LABEL_REF ? "i" : "in", file);
3124
 
3125
  else if (letter == 'P')
3126
    {
3127
      if (code == LABEL_REF)
3128
        output_addr_const (file, op);
3129
      else if (code != PC)
3130
        output_operand_lossage ("invalid %%P operand");
3131
    }
3132
 
3133
  else if (letter == 'p')
3134
    {
3135
      int value;
3136
      if (code != CONST_INT
3137
          || (value = exact_log2 (INTVAL (op))) < 0)
3138
        output_operand_lossage ("invalid %%p value");
3139
      else
3140
        fprintf (file, "%d", value);
3141
    }
3142
 
3143
  else if (letter == 'Z')
3144
    {
3145
      gcc_unreachable ();
3146
    }
3147
 
3148
  else if (code == REG || code == SUBREG)
3149
    {
3150
      int regnum;
3151
 
3152
      if (code == REG)
3153
        regnum = REGNO (op);
3154
      else
3155
        regnum = true_regnum (op);
3156
 
3157
      if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
3158
          || (letter == 'L' && WORDS_BIG_ENDIAN)
3159
          || letter == 'D')
3160
        regnum++;
3161
 
3162
      fprintf (file, "%s", reg_names[regnum]);
3163
    }
3164
 
3165
  else if (code == MEM)
3166
    {
3167
      if (letter == 'D')
3168
        output_address (plus_constant (XEXP (op, 0), 4));
3169
      else
3170
        output_address (XEXP (op, 0));
3171
    }
3172
 
3173
  else if (code == CONST_DOUBLE
3174
           && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
3175
    {
3176
      char s[60];
3177
 
3178
      real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1);
3179
      fputs (s, file);
3180
    }
3181
 
3182
  else if (letter == 'x' && GET_CODE (op) == CONST_INT)
3183
    fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
3184
 
3185
  else if (letter == 'X' && GET_CODE(op) == CONST_INT)
3186
    fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16));
3187
 
3188
  else if (letter == 'd' && GET_CODE(op) == CONST_INT)
3189
    fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
3190
 
3191
  else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
3192
    fputs (reg_names[GP_REG_FIRST], file);
3193
 
3194
  else if (letter == 'd' || letter == 'x' || letter == 'X')
3195
    output_operand_lossage ("invalid use of %%d, %%x, or %%X");
3196
 
3197
  else if (letter == 'B')
3198
    fputs (code == EQ ? "z" : "n", file);
3199
  else if (letter == 'b')
3200
    fputs (code == EQ ? "n" : "z", file);
3201
  else if (letter == 'T')
3202
    fputs (code == EQ ? "f" : "t", file);
3203
  else if (letter == 't')
3204
    fputs (code == EQ ? "t" : "f", file);
3205
 
3206
  else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG)
3207
    {
3208
      iq2000_print_operand (file, XEXP (op, 0), letter);
3209
    }
3210
 
3211
  else
3212
    output_addr_const (file, op);
3213
}
3214
 
3215
static bool
3216
iq2000_print_operand_punct_valid_p (unsigned char code)
3217
{
3218
  return iq2000_print_operand_punct[code];
3219
}
3220
 
3221
/* For the IQ2000, transform:
3222
 
3223
        memory(X + <large int>)
3224
   into:
3225
        Y = <large int> & ~0x7fff;
3226
        Z = X + Y
3227
        memory (Z + (<large int> & 0x7fff));
3228
*/
3229
 
3230
rtx
3231
iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
3232
                           enum machine_mode mode)
3233
{
3234
  if (TARGET_DEBUG_B_MODE)
3235
    {
3236
      GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
3237
      GO_DEBUG_RTX (xinsn);
3238
    }
3239
 
3240
  if (iq2000_check_split (xinsn, mode))
3241
    {
3242
      return gen_rtx_LO_SUM (Pmode,
3243
                             copy_to_mode_reg (Pmode,
3244
                                               gen_rtx_HIGH (Pmode, xinsn)),
3245
                             xinsn);
3246
    }
3247
 
3248
  if (GET_CODE (xinsn) == PLUS)
3249
    {
3250
      rtx xplus0 = XEXP (xinsn, 0);
3251
      rtx xplus1 = XEXP (xinsn, 1);
3252
      enum rtx_code code0 = GET_CODE (xplus0);
3253
      enum rtx_code code1 = GET_CODE (xplus1);
3254
 
3255
      if (code0 != REG && code1 == REG)
3256
        {
3257
          xplus0 = XEXP (xinsn, 1);
3258
          xplus1 = XEXP (xinsn, 0);
3259
          code0 = GET_CODE (xplus0);
3260
          code1 = GET_CODE (xplus1);
3261
        }
3262
 
3263
      if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
3264
          && code1 == CONST_INT && !SMALL_INT (xplus1))
3265
        {
3266
          rtx int_reg = gen_reg_rtx (Pmode);
3267
          rtx ptr_reg = gen_reg_rtx (Pmode);
3268
 
3269
          emit_move_insn (int_reg,
3270
                          GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
3271
 
3272
          emit_insn (gen_rtx_SET (VOIDmode,
3273
                                  ptr_reg,
3274
                                  gen_rtx_PLUS (Pmode, xplus0, int_reg)));
3275
 
3276
          return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
3277
        }
3278
    }
3279
 
3280
  if (TARGET_DEBUG_B_MODE)
3281
    GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
3282
 
3283
  return xinsn;
3284
}
3285
 
3286
 
3287
static bool
3288
iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
3289
                  int opno ATTRIBUTE_UNUSED, int * total,
3290
                  bool speed ATTRIBUTE_UNUSED)
3291
{
3292
  enum machine_mode mode = GET_MODE (x);
3293
 
3294
  switch (code)
3295
    {
3296
    case MEM:
3297
      {
3298
        int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3299
 
3300
        if (simple_memory_operand (x, mode))
3301
          return COSTS_N_INSNS (num_words);
3302
 
3303
        * total = COSTS_N_INSNS (2 * num_words);
3304
        break;
3305
      }
3306
 
3307
    case FFS:
3308
      * total = COSTS_N_INSNS (6);
3309
      break;
3310
 
3311
    case AND:
3312
    case IOR:
3313
    case XOR:
3314
    case NOT:
3315
      * total = COSTS_N_INSNS (mode == DImode ? 2 : 1);
3316
      break;
3317
 
3318
    case ASHIFT:
3319
    case ASHIFTRT:
3320
    case LSHIFTRT:
3321
      if (mode == DImode)
3322
        * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12);
3323
      else
3324
        * total = COSTS_N_INSNS (1);
3325
    break;
3326
 
3327
    case ABS:
3328
      if (mode == SFmode || mode == DFmode)
3329
        * total = COSTS_N_INSNS (1);
3330
      else
3331
        * total = COSTS_N_INSNS (4);
3332
      break;
3333
 
3334
    case PLUS:
3335
    case MINUS:
3336
      if (mode == SFmode || mode == DFmode)
3337
        * total = COSTS_N_INSNS (6);
3338
      else if (mode == DImode)
3339
        * total = COSTS_N_INSNS (4);
3340
      else
3341
        * total = COSTS_N_INSNS (1);
3342
      break;
3343
 
3344
    case NEG:
3345
      * total = (mode == DImode) ? 4 : 1;
3346
      break;
3347
 
3348
    case MULT:
3349
      if (mode == SFmode)
3350
        * total = COSTS_N_INSNS (7);
3351
      else if (mode == DFmode)
3352
        * total = COSTS_N_INSNS (8);
3353
      else
3354
        * total = COSTS_N_INSNS (10);
3355
      break;
3356
 
3357
    case DIV:
3358
    case MOD:
3359
      if (mode == SFmode)
3360
        * total = COSTS_N_INSNS (23);
3361
      else if (mode == DFmode)
3362
        * total = COSTS_N_INSNS (36);
3363
      else
3364
        * total = COSTS_N_INSNS (69);
3365
      break;
3366
 
3367
    case UDIV:
3368
    case UMOD:
3369
      * total = COSTS_N_INSNS (69);
3370
      break;
3371
 
3372
    case SIGN_EXTEND:
3373
      * total = COSTS_N_INSNS (2);
3374
      break;
3375
 
3376
    case ZERO_EXTEND:
3377
      * total = COSTS_N_INSNS (1);
3378
      break;
3379
 
3380
    case CONST_INT:
3381
      * total = 0;
3382
      break;
3383
 
3384
    case LABEL_REF:
3385
      * total = COSTS_N_INSNS (2);
3386
      break;
3387
 
3388
    case CONST:
3389
      {
3390
        rtx offset = const0_rtx;
3391
        rtx symref = eliminate_constant_term (XEXP (x, 0), & offset);
3392
 
3393
        if (GET_CODE (symref) == LABEL_REF)
3394
          * total = COSTS_N_INSNS (2);
3395
        else if (GET_CODE (symref) != SYMBOL_REF)
3396
          * total = COSTS_N_INSNS (4);
3397
        /* Let's be paranoid....  */
3398
        else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
3399
          * total = COSTS_N_INSNS (2);
3400
        else
3401
          * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2);
3402
        break;
3403
      }
3404
 
3405
    case SYMBOL_REF:
3406
      * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2);
3407
      break;
3408
 
3409
    case CONST_DOUBLE:
3410
      {
3411
        rtx high, low;
3412
 
3413
        split_double (x, & high, & low);
3414
 
3415
        * total = COSTS_N_INSNS (  (high == CONST0_RTX (GET_MODE (high))
3416
                                  || low == CONST0_RTX (GET_MODE (low)))
3417
                                   ? 2 : 4);
3418
        break;
3419
      }
3420
 
3421
    default:
3422
      return false;
3423
    }
3424
  return true;
3425
}
3426
 
3427
/* Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE.  */
3428
 
3429
static void
3430
iq2000_asm_trampoline_template (FILE *f)
3431
{
3432
  fprintf (f, "\t.word\t0x03e00821\t\t# move   $1,$31\n");
3433
  fprintf (f, "\t.word\t0x04110001\t\t# bgezal $0,.+8\n");
3434
  fprintf (f, "\t.word\t0x00000000\t\t# nop\n");
3435
  if (Pmode == DImode)
3436
    {
3437
      fprintf (f, "\t.word\t0xdfe30014\t\t# ld     $3,20($31)\n");
3438
      fprintf (f, "\t.word\t0xdfe2001c\t\t# ld     $2,28($31)\n");
3439
    }
3440
  else
3441
    {
3442
      fprintf (f, "\t.word\t0x8fe30014\t\t# lw     $3,20($31)\n");
3443
      fprintf (f, "\t.word\t0x8fe20018\t\t# lw     $2,24($31)\n");
3444
    }
3445
  fprintf (f, "\t.word\t0x0060c821\t\t# move   $25,$3 (abicalls)\n");
3446
  fprintf (f, "\t.word\t0x00600008\t\t# jr     $3\n");
3447
  fprintf (f, "\t.word\t0x0020f821\t\t# move   $31,$1\n");
3448
  fprintf (f, "\t.word\t0x00000000\t\t# <function address>\n");
3449
  fprintf (f, "\t.word\t0x00000000\t\t# <static chain value>\n");
3450
}
3451
 
3452
/* Worker for TARGET_TRAMPOLINE_INIT.  */
3453
 
3454
static void
3455
iq2000_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3456
{
3457
  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3458
  rtx mem;
3459
 
3460
  emit_block_move (m_tramp, assemble_trampoline_template (),
3461
                   GEN_INT (TRAMPOLINE_CODE_SIZE), BLOCK_OP_NORMAL);
3462
 
3463
  mem = adjust_address (m_tramp, Pmode, TRAMPOLINE_CODE_SIZE);
3464
  emit_move_insn (mem, fnaddr);
3465
  mem = adjust_address (m_tramp, Pmode,
3466
                        TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE (Pmode));
3467
  emit_move_insn (mem, chain_value);
3468
}
3469
 
3470
#include "gt-iq2000.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.