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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [gcc/] [config/] [cr16/] [cr16.c] - Blame information for rev 783

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* Output routines for CR16 processor.
2
   Copyright (C) 2012 Free Software Foundation, Inc.
3
   Contributed by KPIT Cummins Infosystems Limited.
4
 
5
   This file is part of GCC.
6
 
7
   GCC is free software; you can redistribute it and/or modify it
8
   under the terms of the GNU General Public License as published
9
   by the Free Software Foundation; either version 3, or (at your
10
   option) any later version.
11
 
12
   GCC is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   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 "rtl.h"
26
#include "tree.h"
27
#include "tm_p.h"
28
#include "regs.h"
29
#include "hard-reg-set.h"
30
#include "insn-config.h"
31
#include "conditions.h"
32
#include "output.h"
33
#include "insn-codes.h"
34
#include "insn-attr.h"
35
#include "flags.h"
36
#include "except.h"
37
#include "function.h"
38
#include "recog.h"
39
#include "expr.h"
40
#include "optabs.h"
41
#include "diagnostic-core.h"
42
#include "basic-block.h"
43
#include "target.h"
44
#include "target-def.h"
45
#include "df.h"
46
 
47
/* Definitions.  */
48
 
49
/* Maximum number of register used for passing parameters.  */
50
#define MAX_REG_FOR_PASSING_ARGS  6
51
 
52
/* Minimum number register used for passing parameters.  */
53
#define MIN_REG_FOR_PASSING_ARGS  2
54
 
55
/* The maximum count of words supported in the assembly of the architecture in
56
   a push/pop instruction.  */
57
#define MAX_COUNT  8
58
 
59
/* Predicate is true if the current function is a 'noreturn' function,
60
   i.e. it is qualified as volatile.  */
61
#define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl))
62
 
63
/* Predicate that holds when we need to save registers even for 'noreturn'
64
   functions, to accomodate for unwinding.  */
65
#define MUST_SAVE_REGS_P() \
66
  (flag_unwind_tables || (flag_exceptions && !UI_SJLJ))
67
 
68
/* Nonzero if the rtx X is a signed const int of n bits.  */
69
#define RTX_SIGNED_INT_FITS_N_BITS(X, n)                \
70
  ((GET_CODE (X) == CONST_INT                          \
71
   && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
72
 
73
/* Nonzero if the rtx X is an unsigned const int of n bits.  */
74
#define RTX_UNSIGNED_INT_FITS_N_BITS(X, n)               \
75
  ((GET_CODE (X) == CONST_INT                            \
76
   && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0)
77
 
78
/* Structure for stack computations.  */
79
 
80
/* variable definitions in the struture
81
   args_size             Number of bytes saved on the stack for local
82
                         variables
83
 
84
   reg_size              Number of bytes saved on the stack for
85
                         non-scratch registers
86
 
87
   total_size            The sum of 2 sizes: locals vars and padding byte
88
                         for saving the registers. Used in expand_prologue()
89
                         and expand_epilogue()
90
 
91
   last_reg_to_save      Will hold the number of the last register the
92
                         prologue saves, -1 if no register is saved
93
 
94
   save_regs[16]         Each object in the array is a register number.
95
                         Mark 1 for registers that need to be saved
96
 
97
   num_regs              Number of registers saved
98
 
99
   initialized           Non-zero if frame size already calculated, not
100
                         used yet
101
 
102
   function_makes_calls  Does the function make calls ? not used yet.  */
103
 
104
struct cr16_frame_info
105
{
106
  unsigned long var_size;
107
  unsigned long args_size;
108
  unsigned int  reg_size;
109
  unsigned long total_size;
110
  long          last_reg_to_save;
111
  long          save_regs[FIRST_PSEUDO_REGISTER];
112
  int           num_regs;
113
  int           initialized;
114
  int           function_makes_calls;
115
};
116
 
117
/* Current frame information calculated by cr16_compute_frame_size.  */
118
static struct cr16_frame_info current_frame_info;
119
 
120
/* Static Variables.  */
121
 
122
/* Data model that was supplied by user via command line option
123
   This will be overridden in case of invalid combination
124
   of core and data model options are supplied.  */
125
static enum data_model_type data_model = DM_DEFAULT;
126
 
127
/* TARGETM Function Prototypes and forward declarations  */
128
static void cr16_print_operand (FILE *, rtx, int);
129
static void cr16_print_operand_address (FILE *, rtx);
130
 
131
/* Stack layout and calling conventions.  */
132
#undef  TARGET_STRUCT_VALUE_RTX
133
#define TARGET_STRUCT_VALUE_RTX         cr16_struct_value_rtx
134
#undef  TARGET_RETURN_IN_MEMORY
135
#define TARGET_RETURN_IN_MEMORY         cr16_return_in_memory
136
 
137
/* Target-specific uses of '__attribute__'.  */
138
#undef  TARGET_ATTRIBUTE_TABLE
139
#define TARGET_ATTRIBUTE_TABLE          cr16_attribute_table
140
#undef TARGET_NARROW_VOLATILE_BITFIELD
141
#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
142
 
143
/* EH related.  */
144
#undef TARGET_UNWIND_WORD_MODE
145
#define TARGET_UNWIND_WORD_MODE         cr16_unwind_word_mode
146
 
147
/* Override Options.  */
148
#undef TARGET_OPTION_OVERRIDE
149
#define TARGET_OPTION_OVERRIDE          cr16_override_options 
150
 
151
/* Conditional register usuage.  */
152
#undef TARGET_CONDITIONAL_REGISTER_USAGE 
153
#define TARGET_CONDITIONAL_REGISTER_USAGE cr16_conditional_register_usage
154
 
155
/* Controlling register spills.  */
156
#undef TARGET_CLASS_LIKELY_SPILLED_P
157
#define TARGET_CLASS_LIKELY_SPILLED_P   cr16_class_likely_spilled_p
158
 
159
/* Passing function arguments.  */
160
#undef TARGET_FUNCTION_ARG
161
#define TARGET_FUNCTION_ARG             cr16_function_arg
162
#undef TARGET_FUNCTION_ARG_ADVANCE
163
#define TARGET_FUNCTION_ARG_ADVANCE     cr16_function_arg_advance
164
#undef TARGET_RETURN_POPS_ARGS
165
#define TARGET_RETURN_POPS_ARGS         cr16_return_pops_args
166
 
167
/* Initialize the GCC target structure.  */
168
#undef TARGET_FRAME_POINTER_REQUIRED
169
#define TARGET_FRAME_POINTER_REQUIRED   cr16_frame_pointer_required
170
#undef TARGET_CAN_ELIMINATE
171
#define TARGET_CAN_ELIMINATE            cr16_can_eliminate
172
#undef TARGET_LEGITIMIZE_ADDRESS
173
#define TARGET_LEGITIMIZE_ADDRESS       cr16_legitimize_address
174
#undef TARGET_LEGITIMATE_CONSTANT_P
175
#define TARGET_LEGITIMATE_CONSTANT_P    cr16_legitimate_constant_p
176
#undef TARGET_LEGITIMATE_ADDRESS_P
177
#define TARGET_LEGITIMATE_ADDRESS_P     cr16_legitimate_address_p
178
 
179
/* Returning function value.  */
180
#undef TARGET_FUNCTION_VALUE
181
#define TARGET_FUNCTION_VALUE           cr16_function_value
182
#undef TARGET_LIBCALL_VALUE
183
#define TARGET_LIBCALL_VALUE            cr16_libcall_value
184
#undef TARGET_FUNCTION_VALUE_REGNO_P
185
#define TARGET_FUNCTION_VALUE_REGNO_P   cr16_function_value_regno_p
186
 
187
/* printing the values.  */
188
#undef TARGET_PRINT_OPERAND
189
#define TARGET_PRINT_OPERAND            cr16_print_operand
190
#undef TARGET_PRINT_OPERAND_ADDRESS
191
#define TARGET_PRINT_OPERAND_ADDRESS    cr16_print_operand_address
192
 
193
/* Relative costs of operations.  */
194
#undef  TARGET_ADDRESS_COST
195
#define TARGET_ADDRESS_COST             cr16_address_cost
196
#undef TARGET_REGISTER_MOVE_COST
197
#define TARGET_REGISTER_MOVE_COST       cr16_register_move_cost
198
#undef TARGET_MEMORY_MOVE_COST
199
#define TARGET_MEMORY_MOVE_COST         cr16_memory_move_cost
200
 
201
/* Table of machine attributes.  */
202
static const struct attribute_spec cr16_attribute_table[] = {
203
  /* ISRs have special prologue and epilogue requirements.  */
204
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
205
       affects_type_identity }.  */
206
  {"interrupt", 0, 0, false, true, true, NULL, false},
207
  {NULL, 0, 0, false, false, false, NULL, false}
208
};
209
 
210
/* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
211
   .?byte directive along with @c is not understood by assembler.
212
   Therefore, make all TARGET_ASM_UNALIGNED_xx_OP same
213
   as TARGET_ASM_ALIGNED_xx_OP.  */
214
#undef TARGET_ASM_UNALIGNED_HI_OP
215
#define TARGET_ASM_UNALIGNED_HI_OP      TARGET_ASM_ALIGNED_HI_OP
216
#undef TARGET_ASM_UNALIGNED_SI_OP
217
#define TARGET_ASM_UNALIGNED_SI_OP      TARGET_ASM_ALIGNED_SI_OP
218
#undef TARGET_ASM_UNALIGNED_DI_OP
219
#define TARGET_ASM_UNALIGNED_DI_OP      TARGET_ASM_ALIGNED_DI_OP
220
 
221
/* Target hook implementations.  */
222
 
223
/* Implements hook TARGET_RETURN_IN_MEMORY.  */
224
static bool
225
cr16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
226
{
227
  const HOST_WIDE_INT size = int_size_in_bytes (type);
228
  return ((size == -1) || (size > 8));
229
}
230
 
231
/* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
232
static bool
233
cr16_class_likely_spilled_p (reg_class_t rclass)
234
{
235
  if ((rclass) == SHORT_REGS || (rclass) == DOUBLE_BASE_REGS
236
      || (rclass) == LONG_REGS || (rclass) == GENERAL_REGS)
237
    return true;
238
 
239
  return false;
240
}
241
 
242
static int
243
cr16_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
244
                       tree funtype ATTRIBUTE_UNUSED,
245
                       int size ATTRIBUTE_UNUSED)
246
{
247
  return 0;
248
}
249
 
250
/* Returns true if data model selected via command line option
251
   is same as function argument.  */
252
bool
253
cr16_is_data_model (enum data_model_type model)
254
{
255
  return (model == data_model);
256
}
257
 
258
/* Parse relevant options and override.  */
259
static void
260
cr16_override_options (void)
261
{
262
  /* Disable -fdelete-null-pointer-checks option for CR16 target.
263
     Programs which rely on NULL pointer dereferences _not_ halting the
264
     program may not work properly with this option. So disable this
265
     option.  */
266
  flag_delete_null_pointer_checks = 0;
267
 
268
  /* FIXME: To avoid spill_failure ICE during exception handling,
269
   * disable cse_fllow_jumps. The spill error occurs when compiler
270
   * can't find a suitable candidate in GENERAL_REGS class to reload
271
   * a 32bit register.
272
   * Need to find a better way of avoiding this situation. */
273
  if (flag_exceptions)
274
    flag_cse_follow_jumps = 0;
275
 
276
  /* If -fpic option, data_model == DM_FAR.  */
277
  if (flag_pic == NEAR_PIC)
278
    {
279
      data_model = DM_FAR;
280
    }
281
 
282
  /* The only option we want to examine is data model option.  */
283
  if (cr16_data_model)
284
    {
285
      if (strcmp (cr16_data_model, "medium") == 0)
286
        data_model = DM_DEFAULT;
287
      else if (strcmp (cr16_data_model, "near") == 0)
288
        data_model = DM_NEAR;
289
      else if (strcmp (cr16_data_model, "far") == 0)
290
        {
291
          if (TARGET_CR16CP)
292
            data_model = DM_FAR;
293
          else
294
            error ("data-model=far not valid for cr16c architecture");
295
        }
296
      else
297
        error ("invalid data model option -mdata-model=%s", cr16_data_model);
298
    }
299
  else
300
    data_model = DM_DEFAULT;
301
}
302
 
303
/* Implements the macro  TARGET_CONDITIONAL_REGISTER_USAGE.  */
304
static void
305
cr16_conditional_register_usage (void)
306
{
307
  if (flag_pic)
308
    {
309
      fixed_regs[12] = call_used_regs[12] = 1;
310
    }
311
}
312
 
313
/* Stack layout and calling conventions routines.  */
314
 
315
/* Return nonzero if the current function being compiled is an interrupt
316
   function as specified by the "interrupt" attribute.  */
317
int
318
cr16_interrupt_function_p (void)
319
{
320
  tree attributes;
321
 
322
  attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
323
  return (lookup_attribute ("interrupt", attributes) != NULL_TREE);
324
}
325
 
326
/* Compute values for the array current_frame_info.save_regs and the variable
327
   current_frame_info.reg_size. The index of current_frame_info.save_regs
328
   is numbers of register, each will get 1 if we need to save it in the
329
   current function, 0 if not. current_frame_info.reg_size is the total sum
330
   of the registers being saved.  */
331
static void
332
cr16_compute_save_regs (void)
333
{
334
  unsigned int regno;
335
 
336
  /* Initialize here so in case the function is no-return it will be -1.  */
337
  current_frame_info.last_reg_to_save = -1;
338
 
339
  /* Initialize the number of bytes to be saved. */
340
  current_frame_info.reg_size = 0;
341
 
342
  /* No need to save any registers if the function never returns.  */
343
  if (FUNC_IS_NORETURN_P (current_function_decl) && !MUST_SAVE_REGS_P ())
344
    return;
345
 
346
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
347
    {
348
      if (fixed_regs[regno])
349
        {
350
          current_frame_info.save_regs[regno] = 0;
351
          continue;
352
        }
353
 
354
      /* If this reg is used and not call-used (except RA), save it.  */
355
      if (cr16_interrupt_function_p ())
356
        {
357
          if (!current_function_is_leaf && call_used_regs[regno])
358
            /* This is a volatile reg in a non-leaf interrupt routine - save
359
               it for the sake of its sons.  */
360
            current_frame_info.save_regs[regno] = 1;
361
          else if (df_regs_ever_live_p (regno))
362
            /* This reg is used - save it.  */
363
            current_frame_info.save_regs[regno] = 1;
364
          else
365
            /* This reg is not used, and is not a volatile - don't save.  */
366
            current_frame_info.save_regs[regno] = 0;
367
        }
368
      else
369
        {
370
          /* If this reg is used and not call-used (except RA), save it.  */
371
          if (df_regs_ever_live_p (regno)
372
              && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM))
373
            current_frame_info.save_regs[regno] = 1;
374
          else
375
            current_frame_info.save_regs[regno] = 0;
376
        }
377
    }
378
 
379
  /* Save registers so the exception handler can modify them.  */
380
  if (crtl->calls_eh_return)
381
    {
382
      unsigned int i;
383
 
384
      for (i = 0;; ++i)
385
        {
386
          regno = EH_RETURN_DATA_REGNO (i);
387
          if (INVALID_REGNUM == regno)
388
            break;
389
          current_frame_info.save_regs[regno] = 1;
390
        }
391
    }
392
 
393
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
394
    if (current_frame_info.save_regs[regno] == 1)
395
      {
396
        current_frame_info.last_reg_to_save = regno;
397
        if (regno >= CR16_FIRST_DWORD_REGISTER)
398
          current_frame_info.reg_size += CR16_UNITS_PER_DWORD;
399
        else
400
          current_frame_info.reg_size += UNITS_PER_WORD;
401
      }
402
}
403
 
404
/* Compute the size of the local area and the size to be adjusted by the
405
   prologue and epilogue.  */
406
static void
407
cr16_compute_frame (void)
408
{
409
  /* For aligning the local variables.  */
410
  int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
411
  int padding_locals;
412
 
413
  /* Padding needed for each element of the frame.  */
414
  current_frame_info.var_size = get_frame_size ();
415
 
416
  /* Align to the stack alignment.  */
417
  padding_locals = current_frame_info.var_size % stack_alignment;
418
  if (padding_locals)
419
    padding_locals = stack_alignment - padding_locals;
420
 
421
  current_frame_info.var_size += padding_locals;
422
  current_frame_info.total_size = current_frame_info.var_size
423
                                  + (ACCUMULATE_OUTGOING_ARGS
424
                                     ? crtl->outgoing_args_size : 0);
425
}
426
 
427
/* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET.  */
428
int
429
cr16_initial_elimination_offset (int from, int to)
430
{
431
  /* Compute this since we need to use current_frame_info.reg_size.  */
432
  cr16_compute_save_regs ();
433
 
434
  /* Compute this since we need to use current_frame_info.var_size.  */
435
  cr16_compute_frame ();
436
 
437
  if (((from) == FRAME_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
438
    return (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
439
  else if (((from) == ARG_POINTER_REGNUM) && ((to) == FRAME_POINTER_REGNUM))
440
    return (current_frame_info.reg_size + current_frame_info.var_size);
441
  else if (((from) == ARG_POINTER_REGNUM) && ((to) == STACK_POINTER_REGNUM))
442
    return (current_frame_info.reg_size + current_frame_info.var_size
443
            + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0));
444
  else
445
    gcc_unreachable ();
446
}
447
 
448
/* Register Usage.  */
449
 
450
/* Return the class number of the smallest class containing reg number REGNO.
451
   This could be a conditional expression or could index an array.  */
452
enum reg_class
453
cr16_regno_reg_class (int regno)
454
{
455
  if ((regno >= 0) && (regno < CR16_FIRST_DWORD_REGISTER))
456
    return SHORT_REGS;
457
 
458
  if ((regno >= CR16_FIRST_DWORD_REGISTER) && (regno < FIRST_PSEUDO_REGISTER))
459
    return LONG_REGS;
460
 
461
  return NO_REGS;
462
}
463
 
464
/* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
465
int
466
cr16_hard_regno_mode_ok (int regno, enum machine_mode mode)
467
{
468
  if ((GET_MODE_SIZE (mode) >= 4) && (regno == 11))
469
    return 0;
470
 
471
  if (mode == DImode || mode == DFmode)
472
    {
473
      if ((regno > 8) || (regno & 1))
474
        return 0;
475
      return 1;
476
    }
477
 
478
  if ((TARGET_INT32)
479
       && ((regno >= 12) && (GET_MODE_SIZE (mode) < 4 )))
480
     return 0;
481
 
482
  /* CC can only hold CCmode values.  */
483
  if (GET_MODE_CLASS (mode) == MODE_CC)
484
    return 0;
485
  return 1;
486
}
487
 
488
/* Returns register number for function return value.*/
489
static inline unsigned int
490
cr16_ret_register (void)
491
{
492
  return 0;
493
}
494
 
495
/* Implements hook TARGET_STRUCT_VALUE_RTX.  */
496
static rtx
497
cr16_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
498
                       int incoming ATTRIBUTE_UNUSED)
499
{
500
  return gen_rtx_REG (Pmode, cr16_ret_register ());
501
}
502
 
503
/* Returning function value.  */
504
 
505
/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
506
static bool
507
cr16_function_value_regno_p (const unsigned int regno)
508
{
509
  return (regno == cr16_ret_register ());
510
}
511
 
512
/* Create an RTX representing the place where a
513
   library function returns a value of mode MODE.  */
514
static rtx
515
cr16_libcall_value (enum machine_mode mode,
516
                    const_rtx func ATTRIBUTE_UNUSED)
517
{
518
  return gen_rtx_REG (mode, cr16_ret_register ());
519
}
520
 
521
/* Create an RTX representing the place where a
522
   function returns a value of data type VALTYPE.  */
523
static rtx
524
cr16_function_value (const_tree type,
525
                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
526
                     bool outgoing ATTRIBUTE_UNUSED)
527
{
528
  return gen_rtx_REG (TYPE_MODE (type), cr16_ret_register ());
529
}
530
 
531
/* Passing function arguments.  */
532
 
533
/* If enough param regs are available for passing the param of type TYPE return
534
   the number of registers needed else 0.  */
535
static int
536
enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type,
537
                       enum machine_mode mode)
538
{
539
  int type_size;
540
  int remaining_size;
541
 
542
  if (mode != BLKmode)
543
    type_size = GET_MODE_BITSIZE (mode);
544
  else
545
    type_size = int_size_in_bytes (type) * BITS_PER_UNIT;
546
 
547
  remaining_size = BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS
548
                                    - (MIN_REG_FOR_PASSING_ARGS + cum->ints) +
549
                                    1);
550
 
551
  /* Any variable which is too big to pass in two registers, will pass on
552
     stack.  */
553
  if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD))
554
    return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD;
555
 
556
  return 0;
557
}
558
 
559
/* Implements the macro FUNCTION_ARG defined in cr16.h.  */
560
static rtx
561
cr16_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
562
                   const_tree type, bool named ATTRIBUTE_UNUSED)
563
{
564
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
565
  cum->last_parm_in_reg = 0;
566
 
567
  /* function_arg () is called with this type just after all the args have
568
     had their registers assigned. The rtx that function_arg returns from
569
     this type is supposed to pass to 'gen_call' but currently it is not
570
     implemented (see macro GEN_CALL).  */
571
  if (type == void_type_node)
572
    return NULL_RTX;
573
 
574
  if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
575
    return NULL_RTX;
576
 
577
  if (mode == BLKmode)
578
    {
579
      /* Enable structures that need padding bytes at the end to pass to a
580
         function in registers.  */
581
      if (enough_regs_for_param (cum, type, mode) != 0)
582
        {
583
          cum->last_parm_in_reg = 1;
584
          return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
585
        }
586
    }
587
 
588
  if ((MIN_REG_FOR_PASSING_ARGS + cum->ints) > MAX_REG_FOR_PASSING_ARGS)
589
    return NULL_RTX;
590
  else
591
    {
592
      if (enough_regs_for_param (cum, type, mode) != 0)
593
        {
594
          cum->last_parm_in_reg = 1;
595
          return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints);
596
        }
597
    }
598
 
599
  return NULL_RTX;
600
}
601
 
602
/* Implements the macro INIT_CUMULATIVE_ARGS defined in cr16.h.  */
603
void
604
cr16_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
605
                           rtx libfunc ATTRIBUTE_UNUSED)
606
{
607
  tree param, next_param;
608
 
609
  cum->ints = 0;
610
 
611
  /* Determine if this function has variable arguments.  This is indicated by
612
     the last argument being 'void_type_mode' if there are no variable
613
     arguments.  Change here for a different vararg.  */
614
  for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
615
       param != NULL_TREE; param = next_param)
616
    {
617
      next_param = TREE_CHAIN (param);
618
      if ((next_param == NULL_TREE) && (TREE_VALUE (param) != void_type_node))
619
        {
620
          cum->ints = -1;
621
          return;
622
        }
623
    }
624
}
625
 
626
/* Implements the macro FUNCTION_ARG_ADVANCE defined in cr16.h.  */
627
static void
628
cr16_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
629
                           const_tree type, bool named ATTRIBUTE_UNUSED)
630
{
631
  CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
632
 
633
  /* l holds the number of registers required.  */
634
  int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
635
 
636
  /* If the parameter isn't passed on a register don't advance cum.  */
637
  if (!cum->last_parm_in_reg)
638
    return;
639
 
640
  if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))
641
    return;
642
 
643
  if ((mode == SImode) || (mode == HImode)
644
      || (mode == QImode) || (mode == DImode))
645
    {
646
      if (l <= 1)
647
        cum->ints += 1;
648
      else
649
        cum->ints += l;
650
    }
651
  else if ((mode == SFmode) || (mode == DFmode))
652
    cum->ints += l;
653
  else if ((mode) == BLKmode)
654
    {
655
      if ((l = enough_regs_for_param (cum, type, mode)) != 0)
656
        cum->ints += l;
657
    }
658
  return;
659
}
660
 
661
/* Implements the macro FUNCTION_ARG_REGNO_P defined in cr16.h.
662
   Return nonzero if N is a register used for passing parameters.  */
663
int
664
cr16_function_arg_regno_p (int n)
665
{
666
  return ((n <= MAX_REG_FOR_PASSING_ARGS) && (n >= MIN_REG_FOR_PASSING_ARGS));
667
}
668
 
669
/* Addressing modes.
670
   Following set of function implement the macro GO_IF_LEGITIMATE_ADDRESS
671
   defined in cr16.h.  */
672
 
673
/* Helper function to check if is a valid base register that can
674
   hold address.  */
675
static int
676
cr16_addr_reg_p (rtx addr_reg)
677
{
678
  rtx reg;
679
 
680
  if (REG_P (addr_reg))
681
    reg = addr_reg;
682
  else if ((GET_CODE (addr_reg) == SUBREG)
683
           && REG_P (SUBREG_REG (addr_reg))
684
           && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
685
               <= UNITS_PER_WORD))
686
    reg = SUBREG_REG (addr_reg);
687
  else
688
    return FALSE;
689
 
690
  if (GET_MODE (reg) != Pmode)
691
    return FALSE;
692
 
693
  return TRUE;
694
}
695
 
696
/* Helper functions: Created specifically for decomposing operand of CONST
697
   Recursively look into expression x for code or data symbol.
698
   The function expects the expression to contain combination of
699
   SYMBOL_REF, CONST_INT, (PLUS or MINUS)
700
   LABEL_REF, CONST_INT, (PLUS or MINUS)
701
   SYMBOL_REF
702
   LABEL_REF
703
   All other combinations will result in code = -1 and data = ILLEGAL_DM
704
   code data
705
   -1   ILLEGAL_DM   The expression did not contain SYMBOL_REF or LABEL_REF
706
 
707
 
708
    1   ILLEGAL_DM   LABEL_REF was found.
709
    2   ILLEGAL_DM   SYMBOL_REF was found and it was function reference.  */
710
void
711
cr16_decompose_const (rtx x, int *code, enum data_model_type *data,
712
                      bool treat_as_const)
713
{
714
  *code = -1;
715
  *data = ILLEGAL_DM;
716
  switch (GET_CODE (x))
717
    {
718
    case SYMBOL_REF:
719
      *code = SYMBOL_REF_FUNCTION_P (x) ? 2 : 0;
720
      /* 2 indicates func sym.  */
721
      if (*code == 0)
722
        {
723
          if (CR16_TARGET_DATA_NEAR)
724
            *data = DM_DEFAULT;
725
          else if (CR16_TARGET_DATA_MEDIUM)
726
            *data = DM_FAR;
727
          else if (CR16_TARGET_DATA_FAR)
728
            {
729
              if (treat_as_const)
730
                /* This will be used only for printing
731
                   the qualifier. This call is (may be)
732
                   made by cr16_print_operand_address.  */
733
                *data = DM_FAR;
734
              else
735
                /* This call is (may be) made by
736
                   cr16_legitimate_address_p.  */
737
                *data = ILLEGAL_DM;
738
            }
739
        }
740
      return;
741
 
742
    case LABEL_REF:
743
      /* 1 - indicates non-function symbol.  */
744
      *code = 1;
745
      return;
746
 
747
    case PLUS:
748
    case MINUS:
749
      /* Look into the tree nodes.  */
750
      if (GET_CODE (XEXP (x, 0)) == CONST_INT)
751
        cr16_decompose_const (XEXP (x, 1), code, data, treat_as_const);
752
      else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
753
        cr16_decompose_const (XEXP (x, 0), code, data, treat_as_const);
754
      return;
755
    default:
756
      return;
757
    }
758
}
759
 
760
/* Decompose Address
761
   This function decomposes the address returns the type of address
762
   as defined in enum cr16_addrtype.  It also fills the parameter *out.
763
   The decomposed address can be used for two purposes.  One to
764
   check if the address is valid and second to print the address
765
   operand.
766
 
767
   Following tables list valid address supported in CR16C/C+ architectures.
768
   Legend:
769
   aN : Absoulte address N-bit address
770
   R  : One 16-bit register
771
   RP : Consecutive two 16-bit registers or one 32-bit register
772
   I  : One 32-bit register
773
   dispN : Signed displacement of N-bits
774
 
775
   ----Code addresses----
776
   Branch operands:
777
   disp9        : CR16_ABSOLUTE       (disp)
778
   disp17       : CR16_ABSOLUTE       (disp)
779
   disp25       : CR16_ABSOLUTE       (disp)
780
   RP + disp25  : CR16_REGP_REL       (base, disp)
781
 
782
   Jump operands:
783
   RP           : CR16_REGP_REL       (base, disp=0)
784
   a24          : CR16_ABSOLUTE       (disp)
785
 
786
   ----Data addresses----
787
   a20          : CR16_ABSOLUTE       (disp)                near (1M)
788
   a24          : CR16_ABSOLUTE       (disp)                medium  (16M)
789
   R  + d20     : CR16_REG_REL        (base,  disp)         near (1M+64K)
790
   RP + d4      : CR16_REGP_REL       (base,  disp)         far  (4G)
791
   RP + d16     : CR16_REGP_REL       (base,  disp)         far  (4G)
792
   RP + d20     : CR16_REGP_REL       (base,  disp)         far  (4G)
793
   I            : *** Valid but port does not support this
794
   I  + a20     : *** Valid but port does not support this
795
   I  + RP + d14: CR16_INDEX_REGP_REL (base,  index, disp)  far  (4G)
796
   I  + RP + d20: CR16_INDEX_REGP_REL (base,  index, disp)  far  (4G)
797
 
798
   Decomposing Data model in case of absolute address.
799
 
800
   Target Option             Address type Resultant Data ref type
801
   ----------------------    ------------ -----------------------
802
   CR16_TARGET_MODEL_NEAR    ABS20        DM_DEFAULT
803
   CR16_TARGET_MODEL_NEAR    IMM20        DM_DEFAULT
804
   CR16_TARGET_MODEL_NEAR    ABS24        Invalid
805
   CR16_TARGET_MODEL_NEAR    IMM32        Invalid
806
 
807
   CR16_TARGET_MODEL_MEDIUM  ABS20        DM_DEFAULT
808
   CR16_TARGET_MODEL_MEDIUM  IMM20        DM_DEFAULT
809
   CR16_TARGET_MODEL_MEDIUM  ABS24        DM_FAR
810
   CR16_TARGET_MODEL_MEDIUM  IMM32        Invalid
811
 
812
   CR16_TARGET_MODEL_FAR     ABS20        DM_DEFAULT
813
   CR16_TARGET_MODEL_FAR     IMM20        DM_DEFAULT
814
   CR16_TARGET_MODEL_FAR     ABS24        DM_FAR
815
   CR16_TARGET_MODEL_FAR     IMM32        DM_FAR.  */
816
enum cr16_addrtype
817
cr16_decompose_address (rtx addr, struct cr16_address *out,
818
                        bool debug_print, bool treat_as_const)
819
{
820
  rtx base = NULL_RTX, disp = NULL_RTX, index = NULL_RTX;
821
  enum data_model_type data = ILLEGAL_DM;
822
  int code = -1;
823
  enum cr16_addrtype retval = CR16_INVALID;
824
 
825
  switch (GET_CODE (addr))
826
    {
827
    case CONST_INT:
828
      /* Absolute address (known at compile time).  */
829
      code = 0;
830
      if (debug_print)
831
        fprintf (stderr, "\ncode:%d", code);
832
      disp = addr;
833
 
834
      if (debug_print)
835
        {
836
          fprintf (stderr, "\ndisp:");
837
          debug_rtx (disp);
838
        }
839
 
840
      if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
841
        {
842
          data = DM_DEFAULT;
843
          if (debug_print)
844
            fprintf (stderr, "\ndata:%d", data);
845
          retval = CR16_ABSOLUTE;
846
        }
847
      else if (UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 24))
848
        {
849
          if (!CR16_TARGET_DATA_NEAR)
850
            {
851
              data = DM_FAR;
852
              if (debug_print)
853
                fprintf (stderr, "\ndata:%d", data);
854
              retval = CR16_ABSOLUTE;
855
            }
856
          else
857
            return CR16_INVALID;        /* ABS24 is not support in NEAR model.  */
858
        }
859
      else
860
        return CR16_INVALID;
861
      break;
862
 
863
    case CONST:
864
      /* A CONST is an expression of PLUS or MINUS with
865
         CONST_INT, SYMBOL_REF or LABEL_REF. This is the
866
         result of assembly-time arithmetic computation.  */
867
      retval = CR16_ABSOLUTE;
868
      disp = addr;
869
      /* Call the helper function to check the validity.  */
870
      cr16_decompose_const (XEXP (addr, 0), &code, &data, treat_as_const);
871
      if ((code == 0) && (data == ILLEGAL_DM))
872
        /* CONST is not valid code or data address.  */
873
        return CR16_INVALID;
874
      if (debug_print)
875
        {
876
          fprintf (stderr, "\ndisp:");
877
          debug_rtx (disp);
878
          fprintf (stderr, "\ncode:%d", code);
879
          fprintf (stderr, "\ndata:%d", data);
880
        }
881
      break;
882
 
883
    case LABEL_REF:
884
      retval = CR16_ABSOLUTE;
885
      disp = addr;
886
      /* 1 - indicates non-function symbol.  */
887
      code = 1;
888
      if (debug_print)
889
        {
890
          fprintf (stderr, "\ndisp:");
891
          debug_rtx (disp);
892
          fprintf (stderr, "\ncode:%d", code);
893
        }
894
      break;
895
 
896
    case SYMBOL_REF:
897
      /* Absolute address (known at link time).  */
898
      retval = CR16_ABSOLUTE;
899
      disp = addr;
900
      /* This is a code address if symbol_ref is a function.  */
901
      /* 2 indicates func sym.  */
902
      code = SYMBOL_REF_FUNCTION_P (addr) ? 2 : 0;
903
      if (debug_print)
904
        {
905
          fprintf (stderr, "\ndisp:");
906
          debug_rtx (disp);
907
          fprintf (stderr, "\ncode:%d", code);
908
        }
909
      /* If not function ref then check if valid data ref.  */
910
      if (code == 0)
911
        {
912
          if (CR16_TARGET_DATA_NEAR)
913
            data = DM_DEFAULT;
914
          else if (CR16_TARGET_DATA_MEDIUM)
915
            data = DM_FAR;
916
          else if (CR16_TARGET_DATA_FAR)
917
            {
918
              if (treat_as_const)
919
                /* This will be used only for printing the
920
                   qualifier. This call is (may be) made
921
                   by cr16_print_operand_address.  */
922
                data = DM_FAR;
923
              else
924
                /* This call is (may be) made by
925
                   cr16_legitimate_address_p.  */
926
                return CR16_INVALID;
927
            }
928
          else
929
            data = DM_DEFAULT;
930
        }
931
      if (debug_print)
932
        fprintf (stderr, "\ndata:%d", data);
933
      break;
934
 
935
    case REG:
936
    case SUBREG:
937
      /* Register relative address.  */
938
      /* Assume REG fits in a single register.  */
939
      retval = CR16_REG_REL;
940
      if (GET_MODE_BITSIZE (GET_MODE (addr)) > BITS_PER_WORD)
941
        if (!LONG_REG_P (REGNO (addr)))
942
          /* REG will result in reg pair.  */
943
          retval = CR16_REGP_REL;
944
      base = addr;
945
      if (debug_print)
946
        {
947
          fprintf (stderr, "\nbase:");
948
          debug_rtx (base);
949
        }
950
      break;
951
 
952
    case PLUS:
953
      switch (GET_CODE (XEXP (addr, 0)))
954
        {
955
        case REG:
956
        case SUBREG:
957
          /* REG + DISP20.  */
958
          /* All Reg relative addresses having a displacement needs
959
             to fit in 20-bits.  */
960
          disp = XEXP (addr, 1);
961
          if (debug_print)
962
            {
963
              fprintf (stderr, "\ndisp:");
964
              debug_rtx (disp);
965
            }
966
          switch (GET_CODE (XEXP (addr, 1)))
967
            {
968
            case CONST_INT:
969
              /* Shall fit in 20-bits.  */
970
              if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
971
                return CR16_INVALID;
972
              code = 0;
973
              if (debug_print)
974
                fprintf (stderr, "\ncode:%d", code);
975
              break;
976
 
977
            case UNSPEC:
978
              switch (XINT (XEXP (addr, 1), 1))
979
                {
980
                case UNSPEC_LIBRARY_OFFSET:
981
                default:
982
                  gcc_unreachable ();
983
                }
984
              break;
985
 
986
            case LABEL_REF:
987
            case SYMBOL_REF:
988
            case CONST:
989
              /* This is also a valid expression for address.
990
                 However, we cannot ascertain if the resultant
991
                 displacement will be valid 20-bit value.  Therefore,
992
                 lets not allow such an expression for now.  This will
993
                 be updated when  we find a way to validate this
994
                 expression as legitimate address.
995
                 Till then fall through CR16_INVALID.  */
996
            default:
997
              return CR16_INVALID;
998
            }
999
 
1000
          /* Now check if REG can fit into single or pair regs.  */
1001
          retval = CR16_REG_REL;
1002
          base = XEXP (addr, 0);
1003
          if (debug_print)
1004
            {
1005
              fprintf (stderr, "\nbase:");
1006
              debug_rtx (base);
1007
            }
1008
          if (GET_MODE_BITSIZE (GET_MODE ((XEXP (addr, 0)))) > BITS_PER_WORD)
1009
            {
1010
              if (!LONG_REG_P (REGNO ((XEXP (addr, 0)))))
1011
                /* REG will result in reg pair.  */
1012
                retval = CR16_REGP_REL;
1013
            }
1014
          break;
1015
 
1016
        case PLUS:
1017
          /* Valid expr:
1018
             plus
1019
              /\
1020
             /  \
1021
             plus idx
1022
              /\
1023
             /  \
1024
             reg  const_int
1025
 
1026
             Check if the operand 1 is valid index register.  */
1027
          data = ILLEGAL_DM;
1028
          if (debug_print)
1029
            fprintf (stderr, "\ndata:%d", data);
1030
          switch (GET_CODE (XEXP (addr, 1)))
1031
            {
1032
            case REG:
1033
            case SUBREG:
1034
              if (!REG_OK_FOR_INDEX_P (XEXP (addr, 1)))
1035
                return CR16_INVALID;
1036
              /* OK. REG is a valid index register.  */
1037
              index = XEXP (addr, 1);
1038
              if (debug_print)
1039
                {
1040
                  fprintf (stderr, "\nindex:");
1041
                  debug_rtx (index);
1042
                }
1043
              break;
1044
            default:
1045
              return CR16_INVALID;
1046
            }
1047
          /* Check if operand 0 of operand 0 is REGP.  */
1048
          switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))
1049
            {
1050
            case REG:
1051
            case SUBREG:
1052
              /* Now check if REG is a REGP and not in LONG regs.  */
1053
              if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (addr, 0), 0)))
1054
                  > BITS_PER_WORD)
1055
                {
1056
                  if (REGNO (XEXP (XEXP (addr, 0), 0))
1057
                      >= CR16_FIRST_DWORD_REGISTER)
1058
                    return CR16_INVALID;
1059
                  base = XEXP (XEXP (addr, 0), 0);
1060
                  if (debug_print)
1061
                    {
1062
                      fprintf (stderr, "\nbase:");
1063
                      debug_rtx (base);
1064
                    }
1065
                }
1066
              else
1067
                return CR16_INVALID;
1068
              break;
1069
            default:
1070
              return CR16_INVALID;
1071
            }
1072
          /* Now check if the operand 1 of operand 0 is const_int.  */
1073
          if (GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
1074
            {
1075
              disp = XEXP (XEXP (addr, 0), 1);
1076
              if (debug_print)
1077
                {
1078
                  fprintf (stderr, "\ndisp:");
1079
                  debug_rtx (disp);
1080
                }
1081
              if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), 20))
1082
                return CR16_INVALID;
1083
            }
1084
          else
1085
            return CR16_INVALID;
1086
          retval = CR16_INDEX_REGP_REL;
1087
          break;
1088
        default:
1089
          return CR16_INVALID;
1090
        }
1091
      break;
1092
 
1093
    default:
1094
      return CR16_INVALID;
1095
    }
1096
 
1097
  /* Check if the base and index registers are valid.  */
1098
  if (base && !(cr16_addr_reg_p (base)))
1099
    return CR16_INVALID;
1100
  if (base && !(CR16_REG_OK_FOR_BASE_P (base)))
1101
    return CR16_INVALID;
1102
  if (index && !(REG_OK_FOR_INDEX_P (index)))
1103
    return CR16_INVALID;
1104
 
1105
  /* Write the decomposition to out parameter.  */
1106
  out->base = base;
1107
  out->disp = disp;
1108
  out->index = index;
1109
  out->data = data;
1110
  out->code = code;
1111
 
1112
  return retval;
1113
}
1114
 
1115
/* Return non-zero value if 'x' is legitimate PIC operand
1116
   when generating PIC code.  */
1117
int
1118
legitimate_pic_operand_p (rtx x)
1119
{
1120
  switch (GET_CODE (x))
1121
    {
1122
    case SYMBOL_REF:
1123
      return 0;
1124
      break;
1125
    case LABEL_REF:
1126
      return 0;
1127
      break;
1128
    case CONST:
1129
      /* REVISIT: Use something like symbol_referenced_p.  */
1130
      if (GET_CODE (XEXP (x, 0)) == PLUS
1131
          && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1132
              || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
1133
          && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1134
        return 0;
1135
      break;
1136
    case MEM:
1137
      return legitimate_pic_operand_p (XEXP (x, 0));
1138
      break;
1139
    default:
1140
      break;
1141
    }
1142
  return 1;
1143
}
1144
 
1145
/* Convert a non-PIC address in `orig' to a PIC address in `reg'.
1146
 
1147
     Input            Output (-f pic)        Output (-f PIC)
1148
     orig             reg
1149
 
1150
     C1   symbol           symbol@BRO (r12)        symbol@GOT (r12)
1151
 
1152
     C2   symbol + offset  symbol+offset@BRO (r12) symbol+offset@GOT (r12)
1153
 
1154
     NOTE: @BRO is added using unspec:BRO
1155
     NOTE: @GOT is added using unspec:GOT.  */
1156
rtx
1157
legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
1158
                        rtx reg)
1159
{
1160
  /* First handle a simple SYMBOL_REF or LABEL_REF.  */
1161
  if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
1162
    {
1163
      if (reg == 0)
1164
        reg = gen_reg_rtx (Pmode);
1165
 
1166
      if (flag_pic == NEAR_PIC)
1167
        {
1168
          /* Unspec to handle -fpic option.  */
1169
          emit_insn (gen_unspec_bro_addr (reg, orig));
1170
          emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
1171
        }
1172
      else if (flag_pic == FAR_PIC)
1173
        {
1174
          /* Unspec to handle -fPIC option.  */
1175
          emit_insn (gen_unspec_got_addr (reg, orig));
1176
        }
1177
      return reg;
1178
    }
1179
  else if (GET_CODE (orig) == CONST)
1180
    {
1181
      /* To handle (symbol + offset).  */
1182
      rtx base, offset;
1183
 
1184
      if (GET_CODE (XEXP (orig, 0)) == PLUS
1185
          && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1186
        return orig;
1187
 
1188
      if (reg == 0)
1189
        {
1190
          gcc_assert (can_create_pseudo_p ());
1191
          reg = gen_reg_rtx (Pmode);
1192
        }
1193
 
1194
      gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1195
 
1196
      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1197
      offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1198
                                       base == reg ? 0 : reg);
1199
 
1200
      /* REVISIT: Optimize for const-offsets.  */
1201
      emit_insn (gen_addsi3 (reg, base, offset));
1202
 
1203
      return reg;
1204
    }
1205
  return orig;
1206
}
1207
 
1208
/* Implementation of TARGET_LEGITIMATE_ADDRESS_P.  */
1209
static bool
1210
cr16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
1211
                           rtx addr, bool strict)
1212
{
1213
  enum cr16_addrtype addrtype;
1214
  struct cr16_address address;
1215
 
1216
  if (TARGET_DEBUG_ADDR)
1217
    {
1218
      fprintf (stderr,
1219
               "\n======\nTARGET_LEGITIMATE_ADDRESS_P, mode = %s, strict = %d",
1220
               GET_MODE_NAME (mode), strict);
1221
      debug_rtx (addr);
1222
    }
1223
  addrtype = cr16_decompose_address (addr, &address,
1224
                                     (TARGET_DEBUG_ADDR ? 1 : 0), FALSE);
1225
 
1226
  if (TARGET_DEBUG_ADDR)
1227
    {
1228
      const char *typestr;
1229
 
1230
      switch (addrtype)
1231
        {
1232
        case CR16_INVALID:
1233
          typestr = "invalid";
1234
          break;
1235
        case CR16_ABSOLUTE:
1236
          typestr = "absolute";
1237
          break;
1238
        case CR16_REG_REL:
1239
          typestr = "register relative";
1240
          break;
1241
        case CR16_REGP_REL:
1242
          typestr = "register pair relative";
1243
          break;
1244
        case CR16_INDEX_REGP_REL:
1245
          typestr = "index + register pair relative";
1246
          break;
1247
        default:
1248
          gcc_unreachable ();
1249
        }
1250
      fprintf (stderr, "\ncr16 address type: %s\n", typestr);
1251
    }
1252
 
1253
  if (addrtype == CR16_INVALID)
1254
    return FALSE;
1255
 
1256
  if (strict)
1257
    {
1258
      if (address.base
1259
          && !REGNO_MODE_OK_FOR_BASE_P (REGNO (address.base), mode))
1260
        {
1261
          if (TARGET_DEBUG_ADDR)
1262
            fprintf (stderr, "base register not strict\n");
1263
          return FALSE;
1264
        }
1265
      if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))
1266
        {
1267
          if (TARGET_DEBUG_ADDR)
1268
            fprintf (stderr, "index register not strict\n");
1269
          return FALSE;
1270
        }
1271
    }
1272
 
1273
  /* Return true if addressing mode is register relative.  */
1274
  if (flag_pic)
1275
    {
1276
      if (addrtype == CR16_REG_REL || addrtype == CR16_REGP_REL)
1277
        return TRUE;
1278
      else
1279
        return FALSE;
1280
    }
1281
 
1282
  return TRUE;
1283
}
1284
 
1285
/* Routines to compute costs.  */
1286
 
1287
/* Return cost of the memory address x.  */
1288
static int
1289
cr16_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED)
1290
{
1291
  enum cr16_addrtype addrtype;
1292
  struct cr16_address address;
1293
  int cost = 2;
1294
 
1295
  addrtype = cr16_decompose_address (addr, &address, 0, FALSE);
1296
 
1297
  gcc_assert (addrtype != CR16_INVALID);
1298
 
1299
  /* CR16_ABSOLUTE            : 3
1300
     CR16_REG_REL  (disp !=0) : 4
1301
     CR16_REG_REL  (disp ==0) : 5
1302
     CR16_REGP_REL (disp !=0) : 6
1303
     CR16_REGP_REL (disp ==0) : 7
1304
     CR16_INDEX_REGP_REL (disp !=0) : 8
1305
     CR16_INDEX_REGP_REL (disp ==0) : 9.  */
1306
  switch (addrtype)
1307
    {
1308
    case CR16_ABSOLUTE:
1309
      cost += 1;
1310
      break;
1311
    case CR16_REGP_REL:
1312
      cost += 2;
1313
      /* Fall through.  */
1314
    case CR16_REG_REL:
1315
      cost += 3;
1316
      if (address.disp)
1317
        cost -= 1;
1318
      break;
1319
    case CR16_INDEX_REGP_REL:
1320
      cost += 7;
1321
      if (address.disp)
1322
        cost -= 1;
1323
    default:
1324
      break;
1325
    }
1326
 
1327
  if (TARGET_DEBUG_ADDR)
1328
    {
1329
      fprintf (stderr, "\n======\nmacro TARGET_ADDRESS_COST = %d\n", cost);
1330
      debug_rtx (addr);
1331
    }
1332
 
1333
  return cost;
1334
}
1335
 
1336
 
1337
/* Implement `TARGET_REGISTER_MOVE_COST'.  */
1338
static int
1339
cr16_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1340
                         reg_class_t from ATTRIBUTE_UNUSED, reg_class_t to)
1341
{
1342
  return (to != GENERAL_REGS ? 8 : 2);
1343
}
1344
 
1345
/* Implement `TARGET_MEMORY_MOVE_COST'.  */
1346
 
1347
/* Return the cost of moving data of mode MODE between a register of class
1348
   CLASS and memory; IN is zero if the value is to be written to memory,
1349
   nonzero if it is to be read in. This cost is relative to those in
1350
   REGISTER_MOVE_COST.  */
1351
static int
1352
cr16_memory_move_cost (enum machine_mode mode,
1353
                       reg_class_t rclass ATTRIBUTE_UNUSED,
1354
                       bool in ATTRIBUTE_UNUSED)
1355
{
1356
  /* One LD or ST takes twice the time of a simple reg-reg move.  */
1357
  if (reg_classes_intersect_p (rclass, GENERAL_REGS))
1358
    return (4 * HARD_REGNO_NREGS (0, mode));
1359
  else
1360
    return (100);
1361
}
1362
 
1363
/* Instruction output.  */
1364
 
1365
/* Check if a const_double is ok for cr16 store-immediate instructions.  */
1366
int
1367
cr16_const_double_ok (rtx op)
1368
{
1369
  if (GET_MODE (op) == SFmode)
1370
    {
1371
      REAL_VALUE_TYPE r;
1372
      long l;
1373
      REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1374
      REAL_VALUE_TO_TARGET_SINGLE (r, l);
1375
      return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;
1376
    }
1377
 
1378
  return ((UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4)) &&
1379
          (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4))) ? 1 : 0;
1380
}
1381
 
1382
/* Returns bit position of first 0 or 1 bit.
1383
   It is safe to assume val as 16-bit wide.  */
1384
int
1385
cr16_operand_bit_pos (int val, int bitval)
1386
{
1387
  int i;
1388
  if (bitval == 0)
1389
    val = ~val;
1390
 
1391
  for (i = 0; i < 16; i++)
1392
    if (val & (1 << i))
1393
      break;
1394
  return i;
1395
}
1396
 
1397
/* Implements the macro PRINT_OPERAND defined in cr16.h.  */
1398
static void
1399
cr16_print_operand (FILE * file, rtx x, int code)
1400
{
1401
  int ptr_dereference = 0;
1402
 
1403
  switch (code)
1404
    {
1405
    case 'd':
1406
      {
1407
        const char *cr16_cmp_str;
1408
        switch (GET_CODE (x))
1409
          {
1410
            /* MD: compare (reg, reg or imm) but CR16: cmp (reg or imm, reg)
1411
               -> swap all non symmetric ops.  */
1412
          case EQ:
1413
            cr16_cmp_str = "eq";
1414
            break;
1415
          case NE:
1416
            cr16_cmp_str = "ne";
1417
            break;
1418
          case GT:
1419
            cr16_cmp_str = "lt";
1420
            break;
1421
          case GTU:
1422
            cr16_cmp_str = "lo";
1423
            break;
1424
          case LT:
1425
            cr16_cmp_str = "gt";
1426
            break;
1427
          case LTU:
1428
            cr16_cmp_str = "hi";
1429
            break;
1430
          case GE:
1431
            cr16_cmp_str = "le";
1432
            break;
1433
          case GEU:
1434
            cr16_cmp_str = "ls";
1435
            break;
1436
          case LE:
1437
            cr16_cmp_str = "ge";
1438
            break;
1439
          case LEU:
1440
            cr16_cmp_str = "hs";
1441
            break;
1442
          default:
1443
            gcc_unreachable ();
1444
          }
1445
        fprintf (file, "%s", cr16_cmp_str);
1446
        return;
1447
      }
1448
    case '$':
1449
      putc ('$', file);
1450
      return;
1451
 
1452
    case 'p':
1453
      if (GET_CODE (x) == REG)
1454
        {
1455
          /* For Push instructions, we should not print register pairs.  */
1456
          fprintf (file, "%s", reg_names[REGNO (x)]);
1457
          return;
1458
        }
1459
      break;
1460
 
1461
    case 'b':
1462
      /* Print the immediate address for bal
1463
         'b' is used instead of 'a' to avoid compiler calling
1464
         the GO_IF_LEGITIMATE_ADDRESS which cannot
1465
         perform checks on const_int code addresses as it
1466
         assumes all const_int are data addresses.  */
1467
      fprintf (file, "0x%lx", INTVAL (x));
1468
      return;
1469
 
1470
    case 'r':
1471
      /* Print bit position of first 0.  */
1472
      fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 0));
1473
      return;
1474
 
1475
    case 's':
1476
      /* Print bit position of first 1.  */
1477
      fprintf (file, "%d", cr16_operand_bit_pos (INTVAL (x), 1));
1478
      return;
1479
    case 'g':
1480
      /* 'g' is used for implicit mem: dereference.  */
1481
      ptr_dereference = 1;
1482
    case 'f':
1483
    case 0:
1484
      /* default.  */
1485
      switch (GET_CODE (x))
1486
        {
1487
        case REG:
1488
          if (GET_MODE_BITSIZE (GET_MODE (x)) > BITS_PER_WORD)
1489
            {
1490
              if (LONG_REG_P (REGNO (x)))
1491
                fprintf (file, "(%s)", reg_names[REGNO (x)]);
1492
              else
1493
                fprintf (file, "(%s,%s)", reg_names[REGNO (x) + 1],
1494
                         reg_names[REGNO (x)]);
1495
            }
1496
          else
1497
            fprintf (file, "%s", reg_names[REGNO (x)]);
1498
          return;
1499
 
1500
        case MEM:
1501
          output_address (XEXP (x, 0));
1502
          return;
1503
 
1504
        case CONST_DOUBLE:
1505
          {
1506
            REAL_VALUE_TYPE r;
1507
            long l;
1508
 
1509
            REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1510
            REAL_VALUE_TO_TARGET_SINGLE (r, l);
1511
 
1512
            fprintf (file, "$0x%lx", l);
1513
            return;
1514
          }
1515
        case CONST_INT:
1516
          {
1517
            fprintf (file, "$%ld", INTVAL (x));
1518
            return;
1519
          }
1520
        case UNSPEC:
1521
          switch (XINT (x, 1))
1522
            {
1523
            default:
1524
              gcc_unreachable ();
1525
            }
1526
          break;
1527
 
1528
        default:
1529
          if (!ptr_dereference)
1530
            {
1531
              putc ('$', file);
1532
            }
1533
          cr16_print_operand_address (file, x);
1534
          return;
1535
        }
1536
    default:
1537
      output_operand_lossage ("invalid %%xn code");
1538
    }
1539
 
1540
  gcc_unreachable ();
1541
}
1542
 
1543
/* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h.  */
1544
 
1545
static void
1546
cr16_print_operand_address (FILE * file, rtx addr)
1547
{
1548
  enum cr16_addrtype addrtype;
1549
  struct cr16_address address;
1550
 
1551
  /* Decompose the address. Also ask it to treat address as constant.  */
1552
  addrtype = cr16_decompose_address (addr, &address, 0, TRUE);
1553
 
1554
  if (address.disp && GET_CODE (address.disp) == UNSPEC)
1555
    {
1556
      debug_rtx (addr);
1557
    }
1558
 
1559
  switch (addrtype)
1560
    {
1561
    case CR16_REG_REL:
1562
      if (address.disp)
1563
        {
1564
          if (GET_CODE (address.disp) == UNSPEC)
1565
            cr16_print_operand (file, address.disp, 0);
1566
          else
1567
            output_addr_const (file, address.disp);
1568
        }
1569
      else
1570
        fprintf (file, "0");
1571
      fprintf (file, "(%s)", reg_names[REGNO (address.base)]);
1572
      break;
1573
 
1574
    case CR16_ABSOLUTE:
1575
      if (address.disp)
1576
        output_addr_const (file, address.disp);
1577
      else
1578
        fprintf (file, "0");
1579
      break;
1580
 
1581
    case CR16_INDEX_REGP_REL:
1582
      fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
1583
      /* Fall through.  */
1584
    case CR16_REGP_REL:
1585
      if (address.disp)
1586
        {
1587
          if (GET_CODE (address.disp) == UNSPEC)
1588
            cr16_print_operand (file, address.disp, 0);
1589
          else
1590
            output_addr_const (file, address.disp);
1591
        }
1592
      else
1593
        fprintf (file, "0");
1594
      fprintf (file, "(%s,%s)", reg_names[REGNO (address.base) + 1],
1595
               reg_names[REGNO (address.base)]);
1596
      break;
1597
    default:
1598
      debug_rtx (addr);
1599
      gcc_unreachable ();
1600
    }
1601
  /* Add qualifiers to the address expression that was just printed.  */
1602
  if (flag_pic < NEAR_PIC && address.code == 0)
1603
    {
1604
      if (address.data == DM_FAR)
1605
        /* Addr contains SYMBOL_REF & far data ptr.  */
1606
        fprintf (file, "@l");
1607
      else if (address.data == DM_DEFAULT)
1608
        /* Addr contains SYMBOL_REF & medium data ptr.  */
1609
        fprintf (file, "@m");
1610
      /* Addr contains SYMBOL_REF & medium data ptr.  */
1611
      else if (address.data == DM_NEAR)
1612
        /* Addr contains SYMBOL_REF & near data ptr.  */
1613
        fprintf (file, "@s");
1614
    }
1615
  else if (flag_pic == NEAR_PIC
1616
           && (address.code == 0) && (address.data == DM_FAR
1617
                                      || address.data == DM_DEFAULT
1618
                                      || address.data == DM_NEAR))
1619
    {
1620
      fprintf (file, "@l");
1621
    }
1622
  else if (flag_pic == NEAR_PIC && address.code == 2)
1623
    {
1624
      fprintf (file, "pic");
1625
    }
1626
  else if (flag_pic == NEAR_PIC && address.code == 1)
1627
    {
1628
      fprintf (file, "@cpic");
1629
    }
1630
 
1631
  else if (flag_pic == FAR_PIC && address.code == 2)
1632
    {
1633
      /* REVISIT: cr16 register indirect jump expects a 1-bit right shifted
1634
         address ! GOTc tells assembler this symbol is a text-address
1635
         This needs to be fixed in such a way that this offset is done
1636
         only in the case where an address is being used for indirect jump
1637
         or call. Determining the potential usage of loadd is of course not
1638
         possible always. Eventually, this has to be fixed in the
1639
         processor.  */
1640
      fprintf (file, "GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1641
    }
1642
  else if (flag_pic == FAR_PIC && address.code == 1)
1643
    {
1644
      fprintf (file, "@cGOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1645
    }
1646
 
1647
  else if (flag_pic == FAR_PIC &&
1648
           (address.data == DM_FAR || address.data == DM_DEFAULT
1649
            || address.data == DM_NEAR))
1650
    {
1651
      fprintf (file, "@GOT (%s)", reg_names[PIC_OFFSET_TABLE_REGNUM]);
1652
    }
1653
}
1654
 
1655
/* Machine description helper functions.  */
1656
 
1657
/* Called from cr16.md. The return value depends on the parameter push_or_pop:
1658
   When push_or_pop is zero -> string for push instructions of prologue.
1659
   When push_or_pop is nonzero -> string for pop/popret/retx in epilogue.
1660
   Relies on the assumptions:
1661
   1. RA is the last register to be saved.
1662
   2. The maximal value of the counter is MAX_COUNT.  */
1663
char *
1664
cr16_prepare_push_pop_string (int push_or_pop)
1665
{
1666
  /* j is the number of registers being saved, takes care that there won't be
1667
     more than 8 in one push/pop instruction.  */
1668
 
1669
  /* For the register mask string.  */
1670
  static char one_inst_str[50];
1671
 
1672
  /* i is the index of current_frame_info.save_regs[], going from 0 until
1673
     current_frame_info.last_reg_to_save.  */
1674
  int i, start_reg;
1675
  int word_cnt;
1676
  int print_ra;
1677
  char *return_str;
1678
 
1679
  /* For reversing on the push instructions if there are more than one.  */
1680
  char *temp_str;
1681
 
1682
  return_str = (char *) xmalloc (160);
1683
  temp_str = (char *) xmalloc (160);
1684
 
1685
  /* Initialize.  */
1686
  memset (return_str, 0, 3);
1687
 
1688
  i = 0;
1689
  while (i <= current_frame_info.last_reg_to_save)
1690
    {
1691
      /* Prepare mask for one instruction.  */
1692
      one_inst_str[0] = 0;
1693
 
1694
      /* To count number of words in one instruction.  */
1695
      word_cnt = 0;
1696
      start_reg = i;
1697
      print_ra = 0;
1698
      while ((word_cnt < MAX_COUNT)
1699
             && (i <= current_frame_info.last_reg_to_save))
1700
        {
1701
          /* For each non consecutive save register,
1702
             a new instruction shall be generated.  */
1703
          if (!current_frame_info.save_regs[i])
1704
            {
1705
              /* Move to next reg and break.  */
1706
              ++i;
1707
              break;
1708
            }
1709
 
1710
          if (i == RETURN_ADDRESS_REGNUM)
1711
            print_ra = 1;
1712
          else
1713
            {
1714
              /* Check especially if adding 2 does not cross the MAX_COUNT.  */
1715
              if ((word_cnt + ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2))
1716
                  >= MAX_COUNT)
1717
                break;
1718
              /* Increase word count by 2 for long registers except RA.   */
1719
              word_cnt += ((i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2);
1720
            }
1721
          ++i;
1722
        }
1723
 
1724
      /* No need to generate any instruction as
1725
         no register or RA needs to be saved.  */
1726
      if ((word_cnt == 0) && (print_ra == 0))
1727
        continue;
1728
 
1729
      /* Now prepare the instruction operands.  */
1730
      if (word_cnt > 0)
1731
        {
1732
          sprintf (one_inst_str, "$%d, %s", word_cnt, reg_names[start_reg]);
1733
          if (print_ra)
1734
            strcat (one_inst_str, ", ra");
1735
        }
1736
      else
1737
        strcat (one_inst_str, "ra");
1738
 
1739
      if (push_or_pop == 1)
1740
        {
1741
          /* Pop instruction.  */
1742
          if (print_ra && !cr16_interrupt_function_p ()
1743
              && !crtl->calls_eh_return)
1744
            /* Print popret if RA is saved and its not a interrupt
1745
               function.  */
1746
            strcpy (temp_str, "\n\tpopret\t");
1747
          else
1748
            strcpy (temp_str, "\n\tpop\t");
1749
 
1750
          strcat (temp_str, one_inst_str);
1751
 
1752
          /* Add the pop instruction list.  */
1753
          strcat (return_str, temp_str);
1754
        }
1755
      else
1756
        {
1757
          /* Push instruction.  */
1758
          strcpy (temp_str, "\n\tpush\t");
1759
          strcat (temp_str, one_inst_str);
1760
 
1761
          /* We need to reverse the order of the instructions if there
1762
             are more than one. (since the pop will not be reversed in
1763
             the epilogue.  */
1764
          strcat (temp_str, return_str);
1765
          strcpy (return_str, temp_str);
1766
        }
1767
    }
1768
 
1769
  if (push_or_pop == 1)
1770
    {
1771
      /* POP.  */
1772
      if (cr16_interrupt_function_p ())
1773
        strcat (return_str, "\n\tretx\n");
1774
      else if (crtl->calls_eh_return)
1775
        {
1776
          /* Add stack adjustment before returning to exception handler
1777
             NOTE: EH_RETURN_STACKADJ_RTX must refer to (r5, r4).  */
1778
          strcat (return_str, "\n\taddd\t (r5, r4), (sp)\t\n");
1779
          strcat (return_str, "\n\tjump\t (ra)\n");
1780
 
1781
          /* But before anything else, undo the adjustment addition done in
1782
             cr16_expand_epilogue ().  */
1783
          strcpy (temp_str, "\n\tsubd\t (r5, r4), (sp)\t\n");
1784
          strcat (temp_str, return_str);
1785
          strcpy (return_str, temp_str);
1786
        }
1787
      else if (!FUNC_IS_NORETURN_P (current_function_decl)
1788
               && !(current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]))
1789
        strcat (return_str, "\n\tjump\t (ra)\n");
1790
    }
1791
 
1792
  /* Skip the newline and the tab in the start of return_str.  */
1793
  return_str += 2;
1794
  return return_str;
1795
}
1796
 
1797
 
1798
/* Generate DWARF2 annotation for multi-push instruction.  */
1799
static void
1800
cr16_create_dwarf_for_multi_push (rtx insn)
1801
{
1802
  rtx dwarf, reg, tmp;
1803
  int i, j, from, to, word_cnt, dwarf_par_index, inc;
1804
  enum machine_mode mode;
1805
  int num_regs = 0, offset = 0, split_here = 0, total_push_bytes = 0;
1806
 
1807
  for (i = 0; i <= current_frame_info.last_reg_to_save; ++i)
1808
    {
1809
      if (current_frame_info.save_regs[i])
1810
        {
1811
          ++num_regs;
1812
          if (i < CR16_FIRST_DWORD_REGISTER)
1813
            total_push_bytes += 2;
1814
          else
1815
            total_push_bytes += 4;
1816
        }
1817
    }
1818
 
1819
  if (!num_regs)
1820
    return;
1821
 
1822
  dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
1823
  dwarf_par_index = num_regs;
1824
 
1825
  from = current_frame_info.last_reg_to_save + 1;
1826
  to = current_frame_info.last_reg_to_save;
1827
  word_cnt = 0;
1828
 
1829
  for (i = current_frame_info.last_reg_to_save; i >= 0;)
1830
    {
1831
      if (!current_frame_info.save_regs[i] || 0 == i || split_here)
1832
        {
1833
          /* This block of regs is pushed in one instruction.  */
1834
          if (0 == i && current_frame_info.save_regs[i])
1835
            from = 0;
1836
 
1837
          for (j = to; j >= from; --j)
1838
            {
1839
              if (j < CR16_FIRST_DWORD_REGISTER)
1840
                {
1841
                  mode = HImode;
1842
                  inc = 1;
1843
                }
1844
              else
1845
                {
1846
                  mode = SImode;
1847
                  inc = 2;
1848
                }
1849
              reg = gen_rtx_REG (mode, j);
1850
              offset += 2 * inc;
1851
              tmp = gen_rtx_SET (VOIDmode,
1852
                                 gen_frame_mem (mode,
1853
                                                plus_constant
1854
                                                (stack_pointer_rtx,
1855
                                                 total_push_bytes - offset)),
1856
                                 reg);
1857
              RTX_FRAME_RELATED_P (tmp) = 1;
1858
              XVECEXP (dwarf, 0, dwarf_par_index--) = tmp;
1859
            }
1860
          from = i;
1861
          to = --i;
1862
          split_here = 0;
1863
          word_cnt = 0;
1864
          continue;
1865
        }
1866
 
1867
      if (i != RETURN_ADDRESS_REGNUM)
1868
        {
1869
          inc = (i < CR16_FIRST_DWORD_REGISTER) ? 1 : 2;
1870
          if (word_cnt + inc >= MAX_COUNT || FRAME_POINTER_REGNUM == i)
1871
            {
1872
              split_here = 1;
1873
              from = i;
1874
              continue;
1875
            }
1876
          word_cnt += inc;
1877
        }
1878
 
1879
      from = i--;
1880
    }
1881
 
1882
  tmp = gen_rtx_SET (SImode, stack_pointer_rtx,
1883
                     gen_rtx_PLUS (SImode, stack_pointer_rtx,
1884
                                   GEN_INT (-offset)));
1885
  RTX_FRAME_RELATED_P (tmp) = 1;
1886
  XVECEXP (dwarf, 0, 0) = tmp;
1887
 
1888
  add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
1889
}
1890
 
1891
/*
1892
CompactRISC CR16 Architecture stack layout:
1893
 
1894
 
1895
    |
1896
    .
1897
    .
1898
    |
1899
    +==================== Sp (x) = Ap (x+1)
1900
      A | Args for functions
1901
      | | called by X and      Dynamically
1902
      | | Dynamic allocations  allocated and
1903
      | | (alloca, variable    deallocated
1904
  Stack | length arrays).
1905
  grows +-------------------- Fp (x)
1906
  down| | Local variables of X
1907
  ward| +--------------------
1908
      | | Regs saved for X-1
1909
      | +==================== Sp (x-1) = Ap (x)
1910
    | Args for func X
1911
    | pushed by X-1
1912
    +-------------------- Fp (x-1)
1913
    |
1914
    |
1915
    V
1916
*/
1917
void
1918
cr16_expand_prologue (void)
1919
{
1920
  rtx insn;
1921
 
1922
  cr16_compute_frame ();
1923
  cr16_compute_save_regs ();
1924
 
1925
  /* If there is no need in push and adjustment to sp, return.  */
1926
  if ((current_frame_info.total_size + current_frame_info.reg_size) == 0)
1927
    return;
1928
 
1929
  if (current_frame_info.last_reg_to_save != -1)
1930
    {
1931
      /* If there are registers to push.  */
1932
      insn = emit_insn (gen_push_for_prologue
1933
                        (GEN_INT (current_frame_info.reg_size)));
1934
      cr16_create_dwarf_for_multi_push (insn);
1935
      RTX_FRAME_RELATED_P (insn) = 1;
1936
    }
1937
 
1938
 
1939
  if (current_frame_info.total_size > 0)
1940
    {
1941
      insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1942
                                    GEN_INT (-current_frame_info.total_size)));
1943
      RTX_FRAME_RELATED_P (insn) = 1;
1944
    }
1945
 
1946
  if (frame_pointer_needed)
1947
    {
1948
      /* Initialize the frame pointer with the value of the stack pointer
1949
         pointing now to the locals.  */
1950
      insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1951
    }
1952
}
1953
 
1954
/* Generate insn that updates the stack for local variables and padding
1955
   for registers we save.   - Generate the appropriate return insn.  */
1956
void
1957
cr16_expand_epilogue (void)
1958
{
1959
  rtx insn;
1960
 
1961
  /* Nonzero if we need to return and pop only RA. This will generate a
1962
     different insn. This differentiate is for the peepholes for call as
1963
     last statement in function.  */
1964
  int only_popret_RA = (current_frame_info.save_regs[RETURN_ADDRESS_REGNUM]
1965
                        && (current_frame_info.reg_size
1966
                            == CR16_UNITS_PER_DWORD));
1967
 
1968
  if (frame_pointer_needed)
1969
    {
1970
      /* Restore the stack pointer with the frame pointers value.  */
1971
      insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1972
    }
1973
 
1974
  if (current_frame_info.total_size > 0)
1975
    {
1976
      insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1977
                                    GEN_INT (current_frame_info.total_size)));
1978
      RTX_FRAME_RELATED_P (insn) = 1;
1979
    }
1980
 
1981
  if (crtl->calls_eh_return)
1982
    {
1983
      /* Add this here so that (r5, r4) is actually loaded with the adjustment
1984
         value; otherwise, the load might be optimized away...
1985
         NOTE: remember to subtract the adjustment before popping the regs
1986
         and add it back before returning.  */
1987
      insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1988
                                    EH_RETURN_STACKADJ_RTX));
1989
    }
1990
 
1991
  if (cr16_interrupt_function_p ())
1992
    {
1993
      insn = emit_jump_insn (gen_interrupt_return ());
1994
      RTX_FRAME_RELATED_P (insn) = 1;
1995
    }
1996
  else if (crtl->calls_eh_return)
1997
    {
1998
      /* Special case, pop what's necessary, adjust SP and jump to (RA).  */
1999
      insn = emit_jump_insn (gen_pop_and_popret_return
2000
                             (GEN_INT (current_frame_info.reg_size)));
2001
      RTX_FRAME_RELATED_P (insn) = 1;
2002
    }
2003
  else if (current_frame_info.last_reg_to_save == -1)
2004
    /* Nothing to pop.  */
2005
    /* Don't output jump for interrupt routine, only retx.  */
2006
    emit_jump_insn (gen_jump_return ());
2007
  else if (only_popret_RA)
2008
    {
2009
      insn = emit_jump_insn (gen_popret_RA_return ());
2010
      RTX_FRAME_RELATED_P (insn) = 1;
2011
    }
2012
  else
2013
    {
2014
      insn = emit_jump_insn (gen_pop_and_popret_return
2015
                             (GEN_INT (current_frame_info.reg_size)));
2016
      RTX_FRAME_RELATED_P (insn) = 1;
2017
    }
2018
}
2019
 
2020
/* Implements FRAME_POINTER_REQUIRED.  */
2021
static bool
2022
cr16_frame_pointer_required (void)
2023
{
2024
  return (cfun->calls_alloca || crtl->calls_eh_return
2025
          || cfun->has_nonlocal_label || crtl->calls_eh_return);
2026
}
2027
 
2028
static bool
2029
cr16_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2030
{
2031
  return (to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true);
2032
}
2033
 
2034
 
2035
/* A C compound statement that attempts to replace X with
2036
   a valid memory address for an operand of mode MODE. WIN
2037
   will be a C statement label elsewhere in the code.
2038
   X will always be the result of a call to break_out_memory_refs (),
2039
   and OLDX will be the operand that was given to that function to
2040
   produce X.
2041
   The code generated by this macro should not alter the
2042
   substructure of X.  If it transforms X into a more legitimate form,
2043
   it should assign X (which will always be a C variable) a new value.  */
2044
static rtx
2045
cr16_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2046
                         enum machine_mode mode ATTRIBUTE_UNUSED)
2047
{
2048
  if (flag_pic)
2049
    return legitimize_pic_address (orig_x, mode, NULL_RTX);
2050
  else
2051
    return x;
2052
}
2053
 
2054
/* Implement TARGET_LEGITIMATE_CONSTANT_P
2055
   Nonzero if X is a legitimate constant for an immediate
2056
   operand on the target machine.  You can assume that X
2057
   satisfies CONSTANT_P. In cr16c treat legitimize float
2058
   constant as an immediate operand.  */
2059
static bool
2060
cr16_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2061
                            rtx x ATTRIBUTE_UNUSED)
2062
{
2063
  return 1;
2064
}
2065
 
2066
void
2067
notice_update_cc (rtx exp)
2068
{
2069
  if (GET_CODE (exp) == SET)
2070
    {
2071
      /* Jumps do not alter the cc's.  */
2072
      if (SET_DEST (exp) == pc_rtx)
2073
        return;
2074
 
2075
      /* Moving register or memory into a register:
2076
         it doesn't alter the cc's, but it might invalidate
2077
         the RTX's which we remember the cc's came from.
2078
         (Note that moving a constant 0 or 1 MAY set the cc's).  */
2079
      if (REG_P (SET_DEST (exp))
2080
          && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
2081
        {
2082
          return;
2083
        }
2084
 
2085
      /* Moving register into memory doesn't alter the cc's.
2086
         It may invalidate the RTX's which we remember the cc's came from.  */
2087
      if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
2088
        {
2089
          return;
2090
        }
2091
    }
2092
 
2093
  CC_STATUS_INIT;
2094
  return;
2095
}
2096
 
2097
static enum machine_mode
2098
cr16_unwind_word_mode (void)
2099
{
2100
  return SImode;
2101
}
2102
 
2103
/* Helper function for md file. This function is used to emit arithmetic
2104
   DI instructions. The argument "num" decides which instruction to be
2105
   printed.  */
2106
const char *
2107
cr16_emit_add_sub_di (rtx *operands, enum rtx_code code)
2108
{
2109
  rtx lo_op[2] ;
2110
  rtx hi0_op[2] ;
2111
  rtx hi1_op[2] ;
2112
 
2113
  lo_op[0] = gen_lowpart (SImode, operands[0]);
2114
  hi0_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 4);
2115
  hi1_op[0] = simplify_gen_subreg (HImode, operands[0], DImode, 6);
2116
 
2117
  lo_op[1] = gen_lowpart (SImode, operands[2]);
2118
  hi0_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 4);
2119
  hi1_op[1] = simplify_gen_subreg (HImode, operands[2], DImode, 6);
2120
 
2121
  switch (code)
2122
  {
2123
    case PLUS:
2124
      {
2125
        output_asm_insn ("addd\t%1, %0", lo_op) ;
2126
        output_asm_insn ("addcw\t%1, %0", hi0_op) ;
2127
        output_asm_insn ("addcw\t%1, %0", hi1_op) ;
2128
        break;
2129
      }
2130
    case MINUS:
2131
      {
2132
        output_asm_insn ("subd\t%1, %0", lo_op) ;
2133
        output_asm_insn ("subcw\t%1, %0", hi0_op) ;
2134
        output_asm_insn ("subcw\t%1, %0", hi1_op) ;
2135
        break;
2136
      }
2137
   default:
2138
     break;
2139
  }
2140
 
2141
  return "";
2142
}
2143
 
2144
 
2145
/* Helper function for md file. This function is used to emit logical
2146
   DI instructions. The argument "num" decides which instruction to be
2147
   printed.  */
2148
const char *
2149
cr16_emit_logical_di (rtx *operands, enum rtx_code code)
2150
{
2151
  rtx lo_op[2] ;
2152
  rtx hi_op[2] ;
2153
 
2154
  lo_op[0] = gen_lowpart (SImode, operands[0]);
2155
  hi_op[0] = simplify_gen_subreg (SImode, operands[0], DImode, 4);
2156
 
2157
  lo_op[1] = gen_lowpart (SImode, operands[2]);
2158
  hi_op[1] = simplify_gen_subreg (SImode, operands[2], DImode, 4);
2159
 
2160
  switch (code)
2161
  {
2162
    case AND:
2163
      {
2164
        output_asm_insn ("andd\t%1, %0", lo_op) ;
2165
        output_asm_insn ("andd\t%1, %0", hi_op) ;
2166
        return "";
2167
      }
2168
    case IOR:
2169
      {
2170
        output_asm_insn ("ord\t%1, %0", lo_op) ;
2171
        output_asm_insn ("ord\t%1, %0", hi_op) ;
2172
        return "";
2173
      }
2174
    case XOR:
2175
      {
2176
        output_asm_insn ("xord\t%1, %0", lo_op) ;
2177
        output_asm_insn ("xord\t%1, %0", hi_op) ;
2178
        return "";
2179
      }
2180
    default:
2181
      break;
2182
  }
2183
 
2184
  return "";
2185
}
2186
 
2187
/* Initialize 'targetm' variable which contains pointers to functions
2188
   and data relating to the target machine.  */
2189
 
2190
struct gcc_target targetm = TARGET_INITIALIZER;

powered by: WebSVN 2.1.0

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