OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [picochip/] [picochip.c] - Blame information for rev 473

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

Line No. Rev Author Line
1 282 jeremybenn
/* Subroutines used for code generation on picoChip processors.
2
   Copyright (C) 2001,2008, 2009   Free Software Foundation, Inc.
3
   Contributed by picoChip Designs Ltd. (http://www.picochip.com)
4
   Maintained by Daniel Towner (daniel.towner@picochip.com) and
5
   Hariharan Sandanagobalane (hariharan@picochip.com)
6
 
7
This file is part of GCC.
8
 
9
GCC is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 3, or (at your option)
12
any later version.
13
 
14
GCC is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with GCC; see the file COPYING3.  If not, see
21
<http://www.gnu.org/licenses/>. */
22
 
23
#include "config.h"
24
#include "system.h"
25
#include "coretypes.h"
26
#include "tm.h"
27
#include "rtl.h"
28
#include "regs.h"
29
#include "hard-reg-set.h"
30
#include "real.h"
31
#include "insn-config.h"
32
#include "conditions.h"
33
#include "insn-attr.h"
34
#include "flags.h"
35
#include "recog.h"
36
#include "obstack.h"
37
#include "tree.h"
38
#include "expr.h"
39
#include "optabs.h"
40
#include "except.h"
41
#include "function.h"
42
#include "output.h"
43
#include "basic-block.h"
44
#include "integrate.h"
45
#include "toplev.h"
46
#include "ggc.h"
47
#include "hashtab.h"
48
#include "tm_p.h"
49
#include "target.h"
50
#include "target-def.h"
51
#include "langhooks.h"
52
#include "reload.h"
53
#include "params.h"
54
 
55
#include "picochip-protos.h"
56
 
57
#include "insn-attr.h"          /* For DFA state_t. */
58
#include "insn-config.h"        /* Required by recog.h */
59
#include "insn-codes.h"         /* For CODE_FOR_? */
60
#include "optabs.h"             /* For GEN_FCN */
61
#include "basic-block.h"        /* UPDATE_LIFE_GLOBAL* for picochip_reorg. */
62
#include "timevar.h"            /* For TV_SCHED2, in picochip_reorg. */
63
#include "libfuncs.h"           /* For memcpy_libfuncs, etc. */
64
#include "df.h"                 /* For df_regs_ever_live_df_regs_ever_live_pp, etc. */
65
 
66
 
67
/* Target AE ISA information. */
68
enum picochip_dfa_type picochip_schedule_type;
69
 
70
bool picochip_has_mul_unit = false;
71
bool picochip_has_mac_unit = false;
72
 
73
/* targetm hook function prototypes. */
74
 
75
void picochip_asm_file_start (void);
76
void picochip_asm_file_end (void);
77
 
78
void picochip_init_libfuncs (void);
79
void picochip_reorg (void);
80
 
81
int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum,
82
                                       enum machine_mode mode,
83
                                       tree type, bool named);
84
 
85
int picochip_sched_lookahead (void);
86
int picochip_sched_issue_rate (void);
87
int picochip_sched_adjust_cost (rtx insn, rtx link,
88
                                       rtx dep_insn, int cost);
89
int picochip_sched_reorder (FILE * file, int verbose, rtx * ready,
90
                                   int *n_readyp, int clock);
91
 
92
void picochip_init_builtins (void);
93
rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
94
 
95
bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total);
96
bool picochip_return_in_memory(const_tree type,
97
                              const_tree fntype ATTRIBUTE_UNUSED);
98
bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
99
 
100
rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED);
101
rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
102
                         bool outgoing ATTRIBUTE_UNUSED);
103
enum reg_class
104
picochip_secondary_reload (bool in_p,
105
                                 rtx x ATTRIBUTE_UNUSED,
106
                                 enum reg_class cla ATTRIBUTE_UNUSED,
107
                                 enum machine_mode mode,
108
                                 secondary_reload_info *sri);
109
void
110
picochip_asm_named_section (const char *name,
111
                            unsigned int flags ATTRIBUTE_UNUSED,
112
                            tree decl ATTRIBUTE_UNUSED);
113
 
114
static rtx picochip_static_chain (const_tree, bool);
115
 
116
/* Lookup table mapping a register number to the earliest containing
117
   class.  Used by REGNO_REG_CLASS.  */
118
const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER] =
119
{
120
  TWIN_REGS, TWIN_REGS, TWIN_REGS, TWIN_REGS,
121
  TWIN_REGS, TWIN_REGS, TWIN_REGS, TWIN_REGS,
122
  TWIN_REGS, TWIN_REGS, TWIN_REGS, TWIN_REGS,
123
  GR_REGS, FRAME_REGS, PTR_REGS, CONST_REGS,
124
  ACC_REGS, CC_REGS, GR_REGS, GR_REGS
125
};
126
 
127
/* picoChip register names. */
128
const char *picochip_regnames[] = REGISTER_NAMES;
129
 
130
/* Define the maximum number of registers which may be used to pass
131
 * parameters to functions. */
132
#define MAX_CALL_PARAMETER_REGS 6
133
 
134
 
135
/* Target scheduling information. */
136
 
137
/* Determine whether we run our final scheduling pass or not.  We always
138
   avoid the normal second scheduling pass.  */
139
int picochip_flag_schedule_insns2;
140
 
141
/* Check if variable tracking needs to be run. */
142
int picochip_flag_var_tracking;
143
 
144
/* This flag indicates whether the next instruction to be output is a
145
   VLIW continuation instruction.  It is used to communicate between
146
   final_prescan_insn and asm_output_opcode. */
147
static int picochip_vliw_continuation = 0;
148
 
149
/* This variable is used to communicate the current instruction
150
   between final_prescan_insn and functions such as asm_output_opcode,
151
   and picochip_get_vliw_alu_id (which are otherwise unable to determine the
152
   current instruction. */
153
static rtx picochip_current_prescan_insn;
154
 
155
static bool picochip_is_delay_slot_pending = 0;
156
 
157
/* When final_prescan_insn is called, it computes information about
158
   the current VLIW packet, and stores it in this structure. When
159
   instructions are output, this state is used to make sure that the
160
   instructions are output in the correct way (e.g., which ALU to use,
161
   whether a macro branch was ever previously a real branch, etc.). */
162
struct vliw_state
163
{
164
  int contains_pico_alu_insn;
165
  int contains_non_cc_alu_insn;
166
  int num_alu_insns_so_far;
167
 
168
  /* Record how many instructions are contained in the packet. */
169
  int num_insns_in_packet;
170
 
171
  /* There was a case for this to be more than 1 */
172
  int num_cfi_labels_deferred;
173
  char cfi_label_name[2][256];  /* Used to record the name of a CFI label
174
                                   emitted inside a VLIW packet. */
175
  char lm_label_name[256];      /* Used to record the name of an LM label. */
176
};
177
 
178
struct vliw_state picochip_current_vliw_state;
179
 
180
/* Save/restore recog_data. */
181
static int picochip_saved_which_alternative;
182
static struct recog_data picochip_saved_recog_data;
183
 
184
/* Determine which ALU to use for the instruction in
185
   picochip_current_prescan_insn. */
186
static char picochip_get_vliw_alu_id (void);
187
 
188
/* Initialize the GCC target structure.  */
189
 
190
#undef TARGET_ASM_FUNCTION_PROLOGUE
191
#define TARGET_ASM_FUNCTION_PROLOGUE picochip_function_prologue
192
 
193
#undef TARGET_ASM_FUNCTION_EPILOGUE
194
#define TARGET_ASM_FUNCTION_EPILOGUE picochip_function_epilogue
195
 
196
#undef TARGET_ASM_INTERNAL_LABEL
197
#define TARGET_ASM_INTERNAL_LABEL picochip_output_internal_label
198
 
199
#undef TARGET_ASM_GLOBALIZE_LABEL
200
#define TARGET_ASM_GLOBALIZE_LABEL picochip_output_global
201
 
202
#undef TARGET_ASM_BYTE_OP
203
#define TARGET_ASM_BYTE_OP ".initByte "
204
#undef TARGET_ASM_ALIGNED_HI_OP
205
#define TARGET_ASM_ALIGNED_HI_OP  ".initWord "
206
#undef TARGET_ASM_UNALIGNED_HI_OP
207
#define TARGET_ASM_UNALIGNED_HI_OP  ".unalignedInitWord "
208
#undef TARGET_ASM_ALIGNED_SI_OP
209
#define TARGET_ASM_ALIGNED_SI_OP ".initLong "
210
#undef TARGET_ASM_UNALIGNED_SI_OP
211
#define TARGET_ASM_UNALIGNED_SI_OP ".unalignedInitLong "
212
 
213
#undef  TARGET_INIT_BUILTINS
214
#define TARGET_INIT_BUILTINS picochip_init_builtins
215
 
216
#undef  TARGET_EXPAND_BUILTIN
217
#define TARGET_EXPAND_BUILTIN picochip_expand_builtin
218
 
219
#undef TARGET_RTX_COSTS
220
#define TARGET_RTX_COSTS picochip_rtx_costs
221
 
222
#undef TARGET_SCHED_ISSUE_RATE
223
#define TARGET_SCHED_ISSUE_RATE picochip_sched_issue_rate
224
 
225
#undef TARGET_SCHED_REORDER
226
#define TARGET_SCHED_REORDER picochip_sched_reorder
227
 
228
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
229
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
230
  picochip_sched_lookahead
231
 
232
#undef TARGET_SCHED_ADJUST_COST
233
#define TARGET_SCHED_ADJUST_COST picochip_sched_adjust_cost
234
 
235
#undef TARGET_ASM_NAMED_SECTION
236
#define TARGET_ASM_NAMED_SECTION picochip_asm_named_section
237
 
238
#undef TARGET_HAVE_NAMED_SECTIONS
239
#define TARGET_HAVE_NAMED_SECTIONS 1
240
 
241
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
242
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS 1
243
 
244
#undef TARGET_INIT_LIBFUNCS
245
#define TARGET_INIT_LIBFUNCS picochip_init_libfuncs
246
 
247
#undef TARGET_ASM_FILE_START
248
#define TARGET_ASM_FILE_START picochip_asm_file_start
249
 
250
#undef TARGET_ASM_FILE_END
251
#define TARGET_ASM_FILE_END picochip_asm_file_end
252
 
253
#undef TARGET_MACHINE_DEPENDENT_REORG
254
#define TARGET_MACHINE_DEPENDENT_REORG picochip_reorg
255
 
256
#undef TARGET_ARG_PARTIAL_BYTES
257
#define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes
258
 
259
#undef TARGET_PROMOTE_FUNCTION_MODE
260
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
261
#undef TARGET_PROMOTE_PROTOTYPES
262
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
263
 
264
/* Target support for Anchored Addresses optimization */
265
#undef TARGET_MIN_ANCHOR_OFFSET
266
#define TARGET_MIN_ANCHOR_OFFSET 0
267
#undef TARGET_MAX_ANCHOR_OFFSET
268
#define TARGET_MAX_ANCHOR_OFFSET 7
269
#undef TARGET_ASM_OUTPUT_ANCHOR
270
#define TARGET_ASM_OUTPUT_ANCHOR  picochip_asm_output_anchor
271
 
272
#undef TARGET_FUNCTION_VALUE
273
#define TARGET_FUNCTION_VALUE picochip_function_value
274
/*
275
#undef TARGET_LIBGCC_CMP_RETURN_MODE
276
#define TARGET_LIBGCC_CMP_RETURN_MODE picochip_libgcc_cmp_return_mode
277
*/
278
 
279
#undef TARGET_LEGITIMATE_ADDRESS_P
280
#define TARGET_LEGITIMATE_ADDRESS_P picochip_legitimate_address_p
281
 
282
/* Loading and storing QImode values to and from memory
283
   usually requires a scratch register. */
284
#undef TARGET_SECONDARY_RELOAD
285
#define TARGET_SECONDARY_RELOAD picochip_secondary_reload
286
#undef DONT_USE_BUILTIN_SETJMP
287
#define DONT_USE_BUILTIN_SETJMP 1
288
 
289
/* How Large Values are Returned  */
290
 
291
#undef TARGET_RETURN_IN_MEMORY
292
#define TARGET_RETURN_IN_MEMORY picochip_return_in_memory
293
 
294
#undef TARGET_STATIC_CHAIN
295
#define TARGET_STATIC_CHAIN picochip_static_chain
296
 
297
struct gcc_target targetm = TARGET_INITIALIZER;
298
 
299
 
300
/* Only return a value in memory if it is greater than 4 bytes.
301
   int_size_in_bytes returns -1 for variable size objects, which go in
302
   memory always.  The cast to unsigned makes -1 > 8.  */
303
 
304
bool
305
picochip_return_in_memory(const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
306
{
307
  return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 4);
308
}
309
 
310
/* Allow certain command options to be overriden. */
311
void
312
picochip_override_options (void)
313
{
314
  /* If we are optimizing for stack, dont let inliner to inline functions
315
     that could potentially increase stack size.*/
316
   if (flag_conserve_stack)
317
   {
318
     PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 0;
319
     PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 0;
320
   }
321
 
322
  /* Turn off the elimination of unused types. The elaborator
323
     generates various interesting types to represent constants,
324
     generics, and so on, and it is useful to retain this information
325
     in the debug output. The increased size of the debug information
326
     is not really an issue for us. */
327
  flag_eliminate_unused_debug_types = 0;
328
 
329
  /* Even if the user specifies a -fno-omit-frame-pointer on the
330
     command line, we still want to go ahead and omit frame pointer
331
     usages, since we dont really have a frame pointer register.
332
     So, all accesses to FP need to be converted to accesses off
333
     stack pointer.*/
334
  flag_omit_frame_pointer = 1;
335
 
336
  /* Turning on anchored addresses by default. This is an optimization
337
     that could decrease the code size by placing anchors in data and
338
     accessing offsets from the anchor for file local data variables.
339
     This isnt the default at O2 as yet. */
340
  flag_section_anchors = 1;
341
 
342
  /* Turn off the second scheduling pass, and move it to
343
     picochip_reorg, to avoid having the second jump optimisation
344
     trash the instruction modes (e.g., instructions are changed to
345
     TImode to mark the beginning of cycles). Two types of DFA
346
     scheduling are possible: space and speed. In both cases,
347
     instructions are reordered to avoid stalls (e.g., memory loads
348
     stall for one cycle). Speed scheduling will also enable VLIW
349
     instruction packing. VLIW instructions use more code space, so
350
     VLIW scheduling is disabled when scheduling for size. */
351
  picochip_flag_schedule_insns2 = flag_schedule_insns_after_reload;
352
  flag_schedule_insns_after_reload = 0;
353
  if (picochip_flag_schedule_insns2)
354
    {
355
 
356
      if (optimize_size)
357
        picochip_schedule_type = DFA_TYPE_SPACE;
358
      else
359
        {
360
          picochip_schedule_type = DFA_TYPE_SPEED;
361
          flag_delayed_branch = 0;
362
        }
363
 
364
    }
365
  else
366
    picochip_schedule_type = DFA_TYPE_NONE;
367
 
368
  /* Ensure that the debug level is always at least -g2. The flow
369
     analyser works at its best if it always has debug
370
     information. DWARF is non-intrusive, so it makes no difference to
371
     code quality if debug is always enabled. */
372
  if (debug_info_level < DINFO_LEVEL_NORMAL)
373
  {
374
    debug_info_level = DINFO_LEVEL_NORMAL;
375
    write_symbols = DWARF2_DEBUG;
376
  }
377
 
378
  /* Options of the form -mae=mac, and so on will be substituted by
379
     the compiler driver for the appropriate byte access and multiply
380
     unit ISA options. Any unrecognised AE types will end up being
381
     passed to the compiler, which should reject them as invalid. */
382
  if (picochip_ae_type_string != NULL)
383
    error ("invalid AE type specified (%s)\n", picochip_ae_type_string);
384
 
385
  /* Override any specific capabilities of the instruction set. These
386
     take precedence over any capabilities inferred from the AE type,
387
     regardless of where the options appear on the command line. */
388
  if (picochip_mul_type_string == NULL)
389
    {
390
      /* Default to MEM-type multiply, for historical compatibility. */
391
      picochip_has_mac_unit = false;
392
      picochip_has_mul_unit = true;
393
    }
394
  else
395
    {
396
      picochip_has_mac_unit = false;
397
      picochip_has_mul_unit = false;
398
 
399
      if (strcmp (picochip_mul_type_string, "mul") == 0)
400
        picochip_has_mul_unit = true;
401
      else if (strcmp (picochip_mul_type_string, "mac") == 0)
402
        picochip_has_mac_unit = true;
403
      else if (strcmp (picochip_mul_type_string, "none") == 0)
404
        { /* Do nothing. Unit types already set to false. */ }
405
      else
406
        error ("Invalid mul type specified (%s) - expected mac, mul or none",
407
               picochip_mul_type_string);
408
    }
409
 
410
}
411
 
412
 
413
/* Initialise the library functions to handle arithmetic on some of
414
   the larger modes. */
415
void
416
picochip_init_libfuncs (void)
417
{
418
  /* 64-bit shifts */
419
  set_optab_libfunc (ashr_optab, DImode, "__ashrdi3");
420
  set_optab_libfunc (ashl_optab, DImode, "__ashldi3");
421
  set_optab_libfunc (lshr_optab, DImode, "__lshrdi3");
422
 
423
  /* 64-bit signed multiplication. */
424
  set_optab_libfunc (smul_optab, DImode, "__muldi3");
425
 
426
  /* Signed division */
427
  set_optab_libfunc (sdiv_optab, HImode, "__divhi3");
428
  set_optab_libfunc (sdiv_optab, DImode, "__divdi3");
429
 
430
  /* Signed modulus */
431
  set_optab_libfunc (smod_optab, HImode, "__modhi3");
432
  set_optab_libfunc (smod_optab, DImode, "__moddi3");
433
 
434
  /* 32-bit count leading Zeros*/
435
  set_optab_libfunc (clz_optab, SImode, "_clzsi2");
436
 
437
  /* 64-bit comparison */
438
  set_optab_libfunc (ucmp_optab, DImode, "__ucmpdi2");
439
  set_optab_libfunc (cmp_optab, DImode, "__cmpdi2");
440
 
441
  /* 64-bit addition and subtraction*/
442
  set_optab_libfunc (add_optab, DImode, "_adddi3");
443
  set_optab_libfunc (sub_optab, DImode, "_subdi3");
444
}
445
 
446
/* Return the register class for letter C.  */
447
enum reg_class
448
picochip_reg_class_from_letter (unsigned c)
449
{
450
  switch (c)
451
    {
452
    case 'k':
453
      return FRAME_REGS;
454
    case 'f':
455
      return PTR_REGS;
456
    case 't':
457
      return TWIN_REGS;
458
    case 'r':
459
      return GR_REGS;
460
    default:
461
      return NO_REGS;
462
    }
463
}
464
 
465
static const int
466
pico_leaf_reg_alloc_order[] = LEAF_REG_ALLOC_ORDER;
467
static const int
468
pico_nonleaf_reg_alloc_order[] = REG_ALLOC_ORDER;
469
 
470
void
471
picochip_order_regs_for_local_alloc (void)
472
{
473
  /* We change the order for leaf functions alone. We put r12 at
474
     the end since using it will prevent us to combine stw/ldws to
475
     stl/ldl and it gives no benefit. In non-leaf functions, we
476
     would anyway saveup/restore r12, so it makes sense to use it.*/
477
 
478
  if (leaf_function_p())
479
  {
480
    memcpy ((char *)reg_alloc_order, (const char *) pico_leaf_reg_alloc_order,
481
            FIRST_PSEUDO_REGISTER * sizeof (int));
482
  }
483
  else
484
  {
485
    memcpy ((char *)reg_alloc_order, (const char *) pico_nonleaf_reg_alloc_order,
486
            FIRST_PSEUDO_REGISTER * sizeof (int));
487
  }
488
}
489
 
490
/* Check that VALUE (an INT_CST) is ok as a constant of type C.  */
491
int
492
picochip_const_ok_for_letter_p (unsigned HOST_WIDE_INT value, unsigned c)
493
{
494
 
495
  switch (c)
496
    {
497
    case 'I':                   /* 4 bits signed.  */
498
      return value + 8 < 16;
499
    case 'J':                   /* 4 bits unsigned.  */
500
      return value < 16;
501
    case 'K':                   /* 8 bits signed.  */
502
      return value + 128 < 256;
503
    case 'M':                   /* 4-bit magnitude. */
504
      return abs (value) < 16;
505
    case 'N':                   /* 10 bits signed.  */
506
      return value + 512 > 1024;
507
    case 'O':                   /* 16 bits signed. */
508
      return value + 32768 < 65536;
509
    default:                    /* Unknown letter. */
510
      return 0;
511
    }
512
}
513
 
514
/* Stack utility functions. */
515
rtx
516
picochip_return_addr_rtx(int count, rtx frameaddr ATTRIBUTE_UNUSED)
517
{
518
   if (count==0)
519
      return gen_rtx_REG (Pmode, LINK_REGNUM);
520
   else
521
      return NULL_RTX;
522
}
523
 
524
 
525
/* Emit a set of parallel register expressions used to store
526
   blockmode values to pass to functions. */
527
static rtx
528
picochip_emit_register_parallel (int size_in_units, int offset)
529
{
530
  int num_regs = 0;
531
  rtx result;
532
  rtx vector[MAX_CALL_PARAMETER_REGS];
533
  int base_reg = 0;
534
  int i = 0;
535
 
536
  /* Compute the base register, and number of required registers. */
537
  base_reg = offset / 2;
538
  num_regs = size_in_units / 2;
539
  if (size_in_units % 2 == 1)
540
    num_regs++;
541
 
542
  /* Emit a register for each part of the block mode value to be
543
     passed in a register. */
544
  for (i = 0; i < num_regs; i++)
545
    vector[i] = gen_rtx_EXPR_LIST (VOIDmode,
546
                                   gen_rtx_REG (HImode, base_reg + i),
547
                                   GEN_INT (i * 2));
548
  result = gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (num_regs, vector));
549
 
550
  return result;
551
 
552
}
553
 
554
/* Emit an instruction to allocate a suitable amount of space on the
555
   stack, by decrementing the stack pointer. */
556
static void
557
picochip_emit_stack_allocate (int adjustment)
558
{
559
  rtx insn;
560
  rtx stack_pointer_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
561
 
562
  /* Use an addition of a negative value. */
563
  insn = emit_insn (gen_addhi3 (stack_pointer_reg, stack_pointer_reg,
564
                                GEN_INT (-adjustment)));
565
 
566
  /* Make the instruction frame related.  Also add an expression note,
567
     so that the correct Dwarf information is generated (see documention
568
     for RTX_FRAME_RELATED_P for more details). */
569
  RTX_FRAME_RELATED_P (insn) = 1;
570
  REG_NOTES (insn) =
571
    gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
572
                       gen_rtx_SET (VOIDmode, stack_pointer_reg,
573
                                    gen_rtx_PLUS (Pmode, stack_pointer_reg,
574
                                                  GEN_INT (-adjustment))),
575
                       REG_NOTES (insn));
576
 
577
}
578
 
579
/* Emit an instruction to save a register of the given mode.  The
580
   offset at which to save the register is given relative to the stack
581
   pointer. */
582
static void
583
picochip_emit_save_register (rtx reg, int offset)
584
{
585
  rtx stack_pointer, address, mem, insn;
586
 
587
  stack_pointer = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
588
 
589
  address = gen_rtx_PLUS (Pmode, stack_pointer, GEN_INT (offset));
590
 
591
  mem = gen_rtx_MEM (GET_MODE (reg), address);
592
 
593
  insn = emit_move_insn (mem, reg);
594
  RTX_FRAME_RELATED_P (insn) = 1;
595
 
596
  /* For modes other than HImode, create a note explaining that
597
     multiple registers have been saved.  This allows the correct DWARF
598
     call frame information to be generated. */
599
  switch (GET_MODE (reg))
600
    {
601
    case HImode:
602
      /* The RTL is sufficient to explain HImode register saves. */
603
      break;
604
 
605
    case SImode:
606
      /* SImode must be broken down into parallel HImode register saves. */
607
      {
608
        rtvec p;
609
        p = rtvec_alloc (2);
610
 
611
        RTVEC_ELT (p, 0) =
612
          gen_rtx_SET (HImode,
613
                       gen_rtx_MEM (HImode,
614
                                    gen_rtx_PLUS (Pmode, stack_pointer,
615
                                                  GEN_INT (offset))),
616
                       gen_rtx_REG (HImode, REGNO (reg)));
617
        RTX_FRAME_RELATED_P (RTVEC_ELT (p, 0)) = 1;
618
 
619
        RTVEC_ELT (p, 1) =
620
          gen_rtx_SET (HImode, gen_rtx_MEM (HImode,
621
                                            gen_rtx_PLUS (Pmode,
622
                                                          stack_pointer,
623
                                                          GEN_INT (offset +
624
                                                                   2))),
625
                       gen_rtx_REG (HImode, REGNO (reg) + 1));
626
        RTX_FRAME_RELATED_P (RTVEC_ELT (p, 1)) = 1;
627
 
628
        REG_NOTES (insn) =
629
          gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
630
                             gen_rtx_PARALLEL (VOIDmode, p),
631
                             REG_NOTES (insn));
632
 
633
      }
634
      break;
635
 
636
    default:
637
      internal_error
638
        ("unexpected mode %s encountered in picochip_emit_save_register\n",
639
         GET_MODE_NAME (GET_MODE (reg)));
640
    }
641
 
642
}
643
 
644
/* Emit an instruction to restore a register of the given mode.  The
645
   offset from which to restore the register is given relative to the
646
   stack pointer. */
647
static void
648
picochip_emit_restore_register (rtx reg, int offset)
649
{
650
  rtx stack_pointer, address, mem, insn;
651
 
652
  stack_pointer = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
653
 
654
  address = gen_rtx_PLUS (Pmode, stack_pointer, GEN_INT (offset));
655
 
656
  mem = gen_rtx_MEM (GET_MODE (reg), address);
657
 
658
  insn = emit_move_insn (reg, mem);
659
 
660
}
661
 
662
/* Check that the given byte offset is aligned to the given number of
663
   bits. */
664
static int
665
picochip_is_aligned (int byte_offset, int bit_alignment)
666
{
667
  int byte_alignment = bit_alignment / BITS_PER_UNIT;
668
  return (byte_offset % byte_alignment) == 0;
669
}
670
 
671
/*****************************************************************************
672
 * Stack layout.
673
 *
674
 * The following section contains code which controls how the stack is
675
 * laid out.
676
 *
677
 * The stack is laid out as follows (high addresses first):
678
 *
679
 *   Incoming arguments
680
 *   Pretend arguments            (ARG PTR)
681
 *   Special registers
682
 *   General registers
683
 *   Frame                         (FP)
684
 *   Outgoing arguments            (SP)
685
 *
686
 * The (constant) offsets of the different areas must be calculated
687
 * relative to the stack area immediately below, and aligned
688
 * appropriately. For example, the frame offset is computed by
689
 * determining the offset of the special register area, adding the
690
 * size of the special register area, and then aligning the resulting
691
 * offset correctly. In turn, the special register offset is computed
692
 * from the general register offset, and so on. This enables the
693
 * different offsets to change size and alignment, without requiring
694
 * the code for other offset calculations to be rewritten.
695
 *
696
 * The argument pointer, and the frame pointer are eliminated wherever
697
 * possible, by replacing them with a constant offset from the stack
698
 * pointer. In the rare cases where constant offsets from the stack
699
 * pointer cannot be computed, another register will be allocated to
700
 * serve as the argument pointer, or the frame pointer.
701
 *
702
 * The save registers are stored at small offsets from the caller, to
703
 * enable the more efficient SP-based ISA instructions to be used.
704
 *
705
 ****************************************************************************/
706
 
707
/* Compute the size of an argument in units. */
708
static int
709
picochip_compute_arg_size (tree type, enum machine_mode mode)
710
{
711
  int type_size_in_units = 0;
712
 
713
  if (type)
714
    type_size_in_units = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
715
  else
716
    type_size_in_units = GET_MODE_SIZE (mode);
717
 
718
  return type_size_in_units;
719
 
720
}
721
 
722
/* Determine where the next outgoing arg should be placed. */
723
rtx
724
picochip_function_arg (CUMULATIVE_ARGS cum, int mode, tree type,
725
                       int named ATTRIBUTE_UNUSED)
726
{
727
  int reg = 0;
728
  int type_align_in_units = 0;
729
  int type_size_in_units;
730
  int new_offset = 0;
731
  int offset_overflow = 0;
732
 
733
  /* VOIDmode is passed when computing the second argument to a `call'
734
     pattern. This can be ignored. */
735
  if (mode == VOIDmode)
736
    return 0;
737
 
738
  /* Compute the alignment and size of the parameter. */
739
  type_align_in_units =
740
    picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT;
741
  type_size_in_units = picochip_compute_arg_size (type, mode);
742
 
743
  /* Compute the correct offset (i.e., ensure that the offset meets
744
     the alignment requirements). */
745
  offset_overflow = cum % type_align_in_units;
746
  if (offset_overflow == 0)
747
    new_offset = cum;
748
  else
749
    new_offset = (cum - offset_overflow) + type_align_in_units;
750
 
751
  if (TARGET_DEBUG)
752
    {
753
      printf ("Function arg:\n");
754
      printf ("  Type valid: %s\n", (type ? "yes" : "no"));
755
      printf ("  Cumulative Value: %d\n", cum);
756
      printf ("  Mode: %s\n", GET_MODE_NAME (mode));
757
      printf ("  Type size: %i units\n", type_size_in_units);
758
      printf ("  Alignment: %i units\n", type_align_in_units);
759
      printf ("  New offset: %i\n", new_offset);
760
      printf ("\n");
761
    }
762
 
763
  /* If the new offset is outside the register space, return. */
764
  if (new_offset >= MAX_CALL_PARAMETER_REGS * 2)
765
    return 0;
766
 
767
  /* If the end of the argument is outside the register space, then
768
     the argument must overlap the register space. Return the first
769
     available register. */
770
  if ((new_offset + type_size_in_units) > (MAX_CALL_PARAMETER_REGS * 2))
771
    return gen_rtx_REG (HImode, new_offset / 2);
772
 
773
  /* Create a register of the required mode to hold the parameter. */
774
  reg = new_offset / 2;
775
  switch (mode)
776
    {
777
    case QImode:
778
    case HImode:
779
    case SImode:
780
    case SFmode:
781
    case DImode:
782
    case DFmode:
783
    case SDmode:
784
    case DDmode:
785
    case CHImode:
786
    case CSImode:
787
    case SCmode:
788
    case CQImode:
789
      return gen_rtx_REG ((enum machine_mode) mode, reg);
790
 
791
    case BLKmode:
792
      {
793
        /* Empty blockmode values can be passed as arguments (e.g.,
794
         * empty structs). These require no registers
795
         * whatsoever. Non-empty blockmode values are passed in a set
796
         * of parallel registers. */
797
        if (type_size_in_units == 0)
798
          return 0;
799
        else
800
          return picochip_emit_register_parallel (type_size_in_units, new_offset);
801
      }
802
 
803
    default:
804
      warning
805
        (0, "Defaulting to stack for %s register creation\n",
806
         GET_MODE_NAME (mode));
807
      break;
808
    }
809
 
810
  return 0;
811
 
812
}
813
 
814
/* Determine where the next incoming function argument will
815
   appear. Normally, this works in exactly the same way as
816
   picochip_function_arg, except when the function in question is a
817
   varadic function. In this case, the incoming arguments all appear
818
   to be passed on the stack (actually, some of the arguments are
819
   passed in registers, which are then pushed onto the stack by the
820
   function prologue). */
821
rtx
822
picochip_incoming_function_arg (CUMULATIVE_ARGS cum, int mode,
823
                                tree type, int named)
824
{
825
 
826
  if (cfun->stdarg)
827
    return 0;
828
  else
829
    return picochip_function_arg (cum, mode, type, named);
830
 
831
}
832
 
833
/* Gives the alignment boundary, in bits, of an argument with the
834
   specified mode.  */
835
int
836
picochip_get_function_arg_boundary (enum machine_mode mode)
837
{
838
  int align;
839
 
840
  if (mode == BLKmode)
841
    align = STACK_BOUNDARY;
842
  else
843
    align = GET_MODE_ALIGNMENT (mode);
844
 
845
  if (align < PARM_BOUNDARY)
846
    align = PARM_BOUNDARY;
847
 
848
  return align;
849
 
850
}
851
 
852
/* Compute partial registers. */
853
int
854
picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
855
                            tree type, bool named ATTRIBUTE_UNUSED)
856
{
857
  int type_align_in_units = 0;
858
  int type_size_in_units;
859
  int new_offset = 0;
860
  int offset_overflow = 0;
861
 
862
  unsigned cum = *((unsigned *) p_cum);
863
 
864
  /* VOIDmode is passed when computing the second argument to a `call'
865
     pattern. This can be ignored. */
866
  if (mode == VOIDmode)
867
    return 0;
868
 
869
  /* Compute the alignment and size of the parameter. */
870
  type_align_in_units =
871
    picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT;
872
  type_size_in_units = picochip_compute_arg_size (type, mode);
873
 
874
  /* Compute the correct offset (i.e., ensure that the offset meets
875
     the alignment requirements). */
876
  offset_overflow = cum % type_align_in_units;
877
  if (offset_overflow == 0)
878
    new_offset = cum;
879
  else
880
    new_offset = (cum - offset_overflow) + type_align_in_units;
881
 
882
  if (TARGET_DEBUG)
883
    {
884
      printf ("Partial function arg nregs:\n");
885
      printf ("  Type valid: %s\n", (type ? "yes" : "no"));
886
      printf ("  Cumulative Value: %d\n", cum);
887
      printf ("  Mode: %s\n", GET_MODE_NAME (mode));
888
      printf ("  Type size: %i units\n", type_size_in_units);
889
      printf ("  Alignment: %i units\n", type_align_in_units);
890
      printf ("  New offset: %i\n", new_offset);
891
      printf ("\n");
892
    }
893
 
894
  /* If the new offset is outside the register space, return. */
895
  if (new_offset >= (MAX_CALL_PARAMETER_REGS * 2))
896
    return 0;
897
 
898
  /* If the end of the argument is outside the register space, then
899
     the argument must overlap the register space. Return the number
900
     of bytes which are passed in registers.  */
901
  if ((new_offset + type_size_in_units) > (MAX_CALL_PARAMETER_REGS * 2))
902
    return ((MAX_CALL_PARAMETER_REGS * 2) - new_offset);
903
 
904
  return 0;
905
 
906
}
907
 
908
/* Advance the cumulative args counter, returning the new counter. */
909
CUMULATIVE_ARGS
910
picochip_arg_advance (const CUMULATIVE_ARGS cum, int mode,
911
                      tree type, int named ATTRIBUTE_UNUSED)
912
{
913
  int type_align_in_units = 0;
914
  int type_size_in_units;
915
  int new_offset = 0;
916
  int offset_overflow = 0;
917
 
918
  /* VOIDmode is passed when computing the second argument to a `call'
919
     pattern. This can be ignored. */
920
  if (mode == VOIDmode)
921
    return 0;
922
 
923
  /* Compute the alignment and size of the parameter. */
924
  type_align_in_units =
925
    picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT;
926
  type_size_in_units = picochip_compute_arg_size (type, mode);
927
 
928
  /* Compute the correct offset (i.e., ensure that the offset meets
929
     the alignment requirements). */
930
  offset_overflow = cum % type_align_in_units;
931
  if (offset_overflow == 0)
932
    new_offset = cum;
933
  else
934
    new_offset = (cum - offset_overflow) + type_align_in_units;
935
 
936
  /* Advance past the last argument. */
937
  new_offset += type_size_in_units;
938
 
939
  return new_offset;
940
 
941
}
942
 
943
/* Determine whether a register needs saving/restoring. It does if it
944
   is live in a function, and isn't a call-used register. */
945
static int
946
picochip_reg_needs_saving (int reg_num)
947
{
948
  return df_regs_ever_live_p(reg_num) && !call_used_regs[reg_num];
949
}
950
 
951
/* Compute and return offset of the main frame. */
952
static int
953
picochip_frame_byte_offset (void)
954
{
955
  gcc_assert(picochip_is_aligned
956
      (crtl->outgoing_args_size, BITS_PER_WORD));
957
 
958
  return crtl->outgoing_args_size;
959
}
960
 
961
/* Return the size of the main frame. */
962
static int
963
picochip_frame_size_in_bytes (void)
964
{
965
  int frame_size = get_frame_size();
966
  int stack_align = STACK_BOUNDARY/BITS_PER_UNIT;
967
  if (!picochip_is_aligned (frame_size, STACK_BOUNDARY))
968
    frame_size = frame_size + (stack_align - frame_size%stack_align);
969
  gcc_assert(picochip_is_aligned (frame_size, STACK_BOUNDARY));
970
  return frame_size;
971
}
972
 
973
/* Compute and return the size (in bytes) of the register save/restore
974
   area for the current function. This only includes the general
975
   purpose registers - the special purpose stack pointer and link
976
   registers are not included in this area. */
977
static int
978
picochip_save_area_size_in_bytes (void)
979
{
980
  int num_regs_to_save = 0;
981
  int i = 0;
982
 
983
  /* Read through all the registers, determining which need to be saved. */
984
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
985
    {
986
      if (picochip_reg_needs_saving (i))
987
        num_regs_to_save += 1;
988
    }
989
 
990
  return num_regs_to_save * UNITS_PER_WORD;
991
 
992
}
993
 
994
/* Compute and return offset of the save area base. */
995
static int
996
picochip_save_area_byte_offset (void)
997
{
998
  int base_offset = (picochip_frame_byte_offset () +
999
                     picochip_frame_size_in_bytes ());
1000
 
1001
  gcc_assert(picochip_is_aligned (base_offset, BITS_PER_WORD));
1002
 
1003
  return base_offset;
1004
 
1005
}
1006
 
1007
/* Compute and return offset of the special register save area. This
1008
   area can be found immediately above the normal save area. It must
1009
   be aligned, to allow the registers to be saved and restored as a
1010
   pair. */
1011
static int
1012
picochip_special_save_area_byte_offset (void)
1013
{
1014
  int byte_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
1015
  int offset = (picochip_save_area_byte_offset () +
1016
                picochip_save_area_size_in_bytes ());
1017
 
1018
  if ((offset % byte_alignment) != 0)
1019
    offset = ((offset / byte_alignment) + 1) * byte_alignment;
1020
 
1021
  return offset;
1022
 
1023
}
1024
 
1025
/* Determine whether the LNK/SP register save/restores can be eliminated. */
1026
static int
1027
picochip_can_eliminate_link_sp_save (void)
1028
{
1029
  /* This deserves some reasoning. The df_regs_ever_live_p call keeps
1030
    changing during optimizations phases. So, this function returns different
1031
    values when called from initial_elimination_offset and then again when it
1032
    is called from prologue/epilogue generation. This means that argument
1033
    accesses become wrong. This wouldnt happen only if we were not using the
1034
    stack at all. The following conditions ensures that.*/
1035
 
1036
  return (current_function_is_leaf &&
1037
          !df_regs_ever_live_p(LINK_REGNUM) &&
1038
          !df_regs_ever_live_p(STACK_POINTER_REGNUM) &&
1039
          (picochip_special_save_area_byte_offset() == 0) &&
1040
          (crtl->args.size == 0) &&
1041
          (crtl->args.pretend_args_size == 0));
1042
}
1043
 
1044
/* Compute the size of the special reg save area (SP and LNK). If the
1045
   SP/LNK registers don't need to be saved, this area can shrink to
1046
   nothing. */
1047
static int
1048
picochip_special_save_area_size_in_bytes (void)
1049
{
1050
 
1051
 
1052
  if (picochip_can_eliminate_link_sp_save ())
1053
    return 0;
1054
  else
1055
    return 2 * UNITS_PER_WORD;
1056
}
1057
 
1058
/* Return the number of pretend arguments. If this function is
1059
   varadic, all the incoming arguments are effectively passed on the
1060
   stack. If this function has real pretend arguments (caused by a
1061
   value being passed partially on the stack and partially in
1062
   registers), then return the number of registers used. */
1063
static int
1064
picochip_pretend_arg_area_size (void)
1065
{
1066
 
1067
  if (crtl->args.pretend_args_size != 0)
1068
    {
1069
      gcc_assert(crtl->args.pretend_args_size % 4 == 0);
1070
 
1071
      return crtl->args.pretend_args_size;
1072
    }
1073
  else if (cfun->stdarg)
1074
    return 12;
1075
  else
1076
    return 0;
1077
 
1078
}
1079
 
1080
/* Compute and return the offset of the pretend arguments. The pretend
1081
   arguments are contiguous with the incoming arguments, and must be
1082
   correctly aligned. */
1083
static int
1084
picochip_pretend_arg_area_byte_offset (void)
1085
{
1086
  int base_offset = 0;
1087
 
1088
  base_offset = (picochip_special_save_area_byte_offset () +
1089
                 picochip_special_save_area_size_in_bytes ());
1090
 
1091
  gcc_assert(picochip_is_aligned (base_offset, STACK_BOUNDARY));
1092
  gcc_assert(picochip_is_aligned
1093
      (base_offset + picochip_pretend_arg_area_size (), STACK_BOUNDARY));
1094
 
1095
  return base_offset;
1096
 
1097
}
1098
 
1099
/* Compute and return the offset of the incoming arguments. If a
1100
   static chain is in use, this will be passed just before the other
1101
   arguments.  This means that the pretend argument mechanism, used in
1102
   variadic functions, doesn't work properly. Thus, static chains work
1103
   on their own, as do variadic functions, but not the combination of
1104
   the two. This isn't really a problem. */
1105
static int
1106
picochip_arg_area_byte_offset (void)
1107
{
1108
  int base_offset = (picochip_pretend_arg_area_byte_offset () +
1109
                     picochip_pretend_arg_area_size ());
1110
 
1111
  /* Add an extra 4 bytes - only an extra 16-bits are required, but
1112
     the alignment on a 32-bit boundary must be maintained. */
1113
  if (cfun->static_chain_decl != NULL)
1114
    {
1115
      gcc_assert (!cfun->stdarg);
1116
      base_offset += 4;
1117
    }
1118
 
1119
  gcc_assert(picochip_is_aligned (base_offset, STACK_BOUNDARY));
1120
 
1121
  return base_offset;
1122
 
1123
}
1124
 
1125
int
1126
picochip_regno_nregs (int regno ATTRIBUTE_UNUSED, int mode)
1127
{
1128
 
1129
  /* Special case - only one register needed. */
1130
  if (GET_MODE_CLASS (mode) == MODE_CC)
1131
    return 1;
1132
 
1133
  /* We actually do not allocate acc0 ever. But, it seems like we need to
1134
  make it look like a allocatable register for the dataflow checks to work
1135
  properly. Note that hard_regno_mode_ok will always return 0 for acc0*/
1136
 
1137
  if (regno == 16)
1138
    return 1;
1139
 
1140
  /* General case - compute how much space in terms of units. */
1141
  return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1142
 
1143
}
1144
 
1145
int
1146
picochip_class_max_nregs (int class, int mode)
1147
{
1148
  int size = ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1149
 
1150
  if (class == ACC_REGS)
1151
    return 1;
1152
 
1153
  if (GET_MODE_CLASS (mode) == MODE_CC)
1154
    return 1;
1155
  else
1156
    return size;
1157
 
1158
}
1159
 
1160
/* Eliminate a register that addresses the stack (e.g., frame pointer,
1161
   argument pointer) by replacing it with a constant offset from the
1162
   main stack register. */
1163
int
1164
initial_elimination_offset (int from, int to)
1165
{
1166
  int offset_from_sp = 0;
1167
 
1168
  if (FRAME_POINTER_REGNUM == from && STACK_POINTER_REGNUM == to)
1169
    offset_from_sp = picochip_frame_byte_offset ();
1170
  else if (ARG_POINTER_REGNUM == from && STACK_POINTER_REGNUM == to)
1171
    offset_from_sp = picochip_pretend_arg_area_byte_offset ();
1172
  else
1173
    gcc_unreachable();
1174
 
1175
  return offset_from_sp;
1176
 
1177
}
1178
 
1179
/* Compute and return the size of the incoming argument area. */
1180
static int
1181
picochip_arg_area_size_in_bytes (void)
1182
{
1183
  return crtl->args.size;
1184
}
1185
 
1186
/* Determine whether the given register is valid. When the strict mode
1187
   is used, only hard registers are valid, otherwise any register is
1188
   valid. */
1189
static int
1190
picochip_legitimate_address_register (rtx x, unsigned strict)
1191
{
1192
 
1193
  /* Sanity check - non-registers shouldn't make it here, but... */
1194
  if (REG != GET_CODE (x))
1195
    return 0;
1196
 
1197
  if (strict)
1198
    return REGNO (x) < FIRST_NONHARD_REGISTER;
1199
  else
1200
    return 1;
1201
 
1202
}
1203
 
1204
/* Determine whether the given constant is in the range required for
1205
   the given base register. */
1206
static int
1207
picochip_const_ok_for_base (enum machine_mode mode, int regno, int offset)
1208
{
1209
  HOST_WIDE_INT corrected_offset;
1210
 
1211
  if (GET_MODE_SIZE (mode) != 0)
1212
    {
1213
      if (GET_MODE_SIZE(mode) <= 4)
1214
      {
1215
         /* We used to allow incorrect offsets if strict is 0. But, this would
1216
            then rely on reload doing the right thing. We have had problems
1217
            there before, and on > 4.3 compiler, there are no benefits. */
1218
         if (offset % GET_MODE_SIZE (mode) != 0)
1219
           return 0;
1220
         corrected_offset = offset / GET_MODE_SIZE (mode);
1221
      }
1222
      else
1223
      {
1224
         if (offset % 4 != 0)
1225
           return 0;
1226
         corrected_offset = offset / 4;
1227
      }
1228
    }
1229
  else
1230
    {
1231
      /* Default to the byte offset as supplied. */
1232
      corrected_offset = offset;
1233
    }
1234
 
1235
  /* The offset from the base register can be different depending upon
1236
     the base register.  The stack/frame/argument pointer offsets can
1237
     all be greater than a simple register-based offset.  Note that the
1238
     frame/argument pointer registers are actually eliminations of the
1239
     stack pointer, so a value which is valid for an offset to, for
1240
     example, the frame pointer, might be invalid for the stack
1241
     pointer once the elimination has occurred.  However, there is no
1242
     need to handle this special case here, as the stack offset is
1243
     always checked after elimination anyway, and the generated code
1244
     seems to have identical performance. */
1245
  if (regno == STACK_POINTER_REGNUM ||
1246
      regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
1247
    return picochip_const_ok_for_letter_p (corrected_offset, 'K');
1248
  else
1249
    return picochip_const_ok_for_letter_p (corrected_offset, 'J');
1250
 
1251
}
1252
 
1253
/* Determine whether a given rtx is a legitimate address for machine_mode
1254
   MODE.  STRICT is non-zero if we're being strict - any pseudo that
1255
   is not a hard register must be a memory reference.  */
1256
bool
1257
picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1258
{
1259
  int valid = 0;
1260
 
1261
  switch (GET_CODE (x))
1262
    {
1263
    case REG:
1264
      valid = picochip_legitimate_address_register (x, strict);
1265
      break;
1266
 
1267
    case PLUS:
1268
      {
1269
        rtx base = XEXP (x, 0);
1270
        rtx offset = XEXP (x, 1);
1271
 
1272
        valid = (REG == GET_CODE (base) &&
1273
                 REGNO_OK_FOR_BASE_P (REGNO(base)) &&
1274
                 picochip_legitimate_address_register (base, strict) &&
1275
                 CONST_INT == GET_CODE (offset) &&
1276
                 picochip_const_ok_for_base (mode, REGNO (base),
1277
                                             INTVAL (offset)));
1278
        break;
1279
      }
1280
 
1281
    case SYMBOL_REF:
1282
      /* The user can select whether a symbol can be used as a memory
1283
         address. Typically, this will decrease execution time (no
1284
         register load is required first), but will increase code size
1285
         (because the symbol will be used several times, rather than
1286
         loaded once into a register.*/
1287
      valid = TARGET_SYMBOL_AS_ADDRESS;
1288
      break;
1289
 
1290
    case CONST:
1291
      {
1292
        /* A constant memory address must be a (plus (symbol_ref)
1293
           (const_int)), and is only allowed when the symbols are
1294
           permitted addresses. */
1295
        rtx inner = XEXP (x, 0);
1296
 
1297
        valid = (TARGET_SYMBOL_AS_ADDRESS &&
1298
                 PLUS == GET_CODE (inner) &&
1299
                 SYMBOL_REF == GET_CODE (XEXP (inner, 0)) &&
1300
                 CONST_INT == GET_CODE (XEXP (inner, 1)));
1301
 
1302
        break;
1303
 
1304
      }
1305
 
1306
    default:
1307
      valid = 0;
1308
    }
1309
 
1310
  return valid;
1311
 
1312
}
1313
 
1314
/* Detect an rtx which matches (plus (symbol_ref) (const_int)). */
1315
int
1316
picochip_symbol_offset (rtx operand)
1317
{
1318
 
1319
  return (PLUS == GET_CODE (operand) &&
1320
          SYMBOL_REF == GET_CODE (XEXP (operand, 0)) &&
1321
          CONST_INT == GET_CODE (XEXP (operand, 1)));
1322
 
1323
}
1324
 
1325
/* Assembly output. */
1326
 
1327
/* The format here should match the format used in the output of
1328
   symbol_ref's elsewhere in this file. */
1329
void
1330
picochip_output_label (FILE * stream, const char name[])
1331
{
1332
  int is_cfi_label = (strncmp (name, "picoMark_LCFI", 13) == 0);
1333
 
1334
  /* If VLIW scheduling is in use, any Call Frame Information labels
1335
     generated inside a packet must have their output deferred until
1336
     the end of the packet. */
1337
  if (picochip_schedule_type == DFA_TYPE_SPEED &&
1338
      is_cfi_label && picochip_vliw_continuation)
1339
    {
1340
      if (picochip_current_vliw_state.num_cfi_labels_deferred == 2)
1341
      {
1342
        internal_error ("LCFI labels have already been deferred.");
1343
      }
1344
      strcpy (picochip_current_vliw_state.cfi_label_name[
1345
                picochip_current_vliw_state.num_cfi_labels_deferred], name);
1346
      picochip_current_vliw_state.num_cfi_labels_deferred++;
1347
    }
1348
  else
1349
    {
1350
      assemble_name (stream, name);
1351
 
1352
      if (strncmp (name, "picoMark_", 9) == 0)
1353
        fprintf (stream, "=\n");
1354
      else
1355
        fprintf (stream, ":\n");
1356
 
1357
    }
1358
 
1359
}
1360
 
1361
/* The format here should match the format used in the output of
1362
   symbol_ref's elsewhere in this file. */
1363
void
1364
picochip_output_labelref (FILE * stream, const char name[])
1365
{
1366
  fprintf (stream, "_%s", name);
1367
}
1368
 
1369
void
1370
picochip_weaken_label (FILE * stream, const char name[])
1371
{
1372
  fprintf (stream, ".weak ");
1373
  assemble_name (stream, name);
1374
  fprintf (stream, "\n");
1375
}
1376
 
1377
/* Return true if the given label (or label prefix) denotes a marker
1378
   label which should be emitted in the form LABEL= */
1379
static int
1380
picochip_is_marker_prefix (const char *prefix)
1381
{
1382
  return (strcmp (prefix, "L") != 0 && strcmp (prefix, "LC") != 0
1383
          && strcmp (prefix, "LP") != 0);
1384
}
1385
 
1386
void
1387
picochip_output_internal_label (FILE * stream, const char *prefix,
1388
                                unsigned long num)
1389
{
1390
 
1391
  /* Emit different types of label, based upon their prefix. They
1392
     are handled differently to allow the assembler to ensure that
1393
     branch target labels are properly aligned, while other labels
1394
     will only serve as code markers, not branch targets. Aligning
1395
     labels unnecessarily can result in much code wastage. */
1396
  if (picochip_is_marker_prefix (prefix))
1397
    {
1398
      /* Special label marker. If it appears in the middle of a VLIW
1399
         packet, defer it until the end of the packet. There has
1400
         never been a need to handle more than one lm label at a time. */
1401
      if (picochip_schedule_type == DFA_TYPE_SPEED &&
1402
          (strcmp (prefix, "LM")) == 0 && picochip_vliw_continuation)
1403
        {
1404
          if (strlen (picochip_current_vliw_state.lm_label_name) != 0)
1405
            internal_error ("LM label has already been deferred.");
1406
 
1407
          sprintf (picochip_current_vliw_state.lm_label_name,
1408
                   "picoMark_%s%ld", prefix, num);
1409
        }
1410
      else
1411
        {
1412
          /* Marker label. */
1413
          fprintf (stream, "_picoMark_%s%ld=\n", prefix, num);
1414
        }
1415
 
1416
    }
1417
  else
1418
    {
1419
      /* Normal label. */
1420
      fprintf (stream, "_%s%ld:\n", prefix, num);
1421
    }
1422
 
1423
}
1424
 
1425
void
1426
picochip_generate_internal_label (char *str, const char *prefix, long num)
1427
{
1428
  /* Two types of internal label can be generated: branch target
1429
     labels and code marker labels. Branch target labels must always
1430
     be aligned (since code will execute at these
1431
     points). Differentiate between the two by prepending markers with
1432
     a unique prefix, which can later be used in output_label to
1433
     figure out which label syntax to use. */
1434
  if (picochip_is_marker_prefix (prefix))
1435
    sprintf (str, "picoMark_%s%ld", prefix, num);
1436
  else
1437
    sprintf (str, "%s%ld", prefix, num);
1438
 
1439
}
1440
 
1441
void
1442
picochip_asm_output_anchor (rtx symbol)
1443
{
1444
  fprintf (asm_out_file, ".offsetData _%s, ",XSTR (symbol, 0));
1445
  fprintf (asm_out_file, "+ " HOST_WIDE_INT_PRINT_DEC"\n",SYMBOL_REF_BLOCK_OFFSET(symbol));
1446
}
1447
 
1448
void
1449
picochip_output_aligned_common (FILE * stream, const char *name,
1450
                                unsigned size, unsigned alignment)
1451
{
1452
 
1453
  fprintf (stream, ".commonData ");
1454
  assemble_name (stream, name);
1455
  fprintf (stream, ", %u, %u\n", size, alignment / 8);
1456
  picochip_output_global (stream, name);
1457
 
1458
}
1459
 
1460
void
1461
picochip_output_aligned_local (FILE * stream, const char *name,
1462
                               unsigned size, unsigned alignment)
1463
{
1464
 
1465
  fprintf (stream, ".commonData ");
1466
  assemble_name (stream, name);
1467
  fprintf (stream, ", %u, %u\n", size, alignment / 8);
1468
 
1469
}
1470
 
1471
void
1472
picochip_output_global (FILE * stream, const char *name)
1473
{
1474
  fprintf (stream, ".global ");
1475
  assemble_name (stream, name);
1476
  fprintf (stream, "\n");
1477
}
1478
 
1479
/* Output an assembly language string. Output as a sequence of decimal
1480
   numbers, followed by the literal string to make it obvious what the
1481
   numbers represent. */
1482
void
1483
picochip_output_ascii (FILE * file, const char *str, int length)
1484
{
1485
  int i = 0;
1486
 
1487
  fprintf (file, ".ascii ");
1488
 
1489
  for (i = 0; i < length; ++i)
1490
    {
1491
      fprintf (file, "16#%hhx# ", (char) (str[i]));
1492
    }
1493
 
1494
  fprintf (file, "  ; ");
1495
 
1496
  for (i = 0; i < length; ++i)
1497
    {
1498
      char c = str[i];
1499
 
1500
      switch (c)
1501
        {
1502
        case '\n':
1503
          fprintf (file, "\\n");
1504
          break;
1505
        case '\t':
1506
          fprintf (file, "\\t");
1507
          break;
1508
        case '\0':
1509
          fprintf (file, "\\0");
1510
          break;
1511
        default:
1512
          fprintf (file, "%c", c);
1513
        }
1514
 
1515
    }
1516
 
1517
  fprintf (file, "\n");
1518
 
1519
}
1520
 
1521
/* Output the beginning of an ASM file. */
1522
void
1523
picochip_asm_file_start (void)
1524
{
1525
  default_file_start ();
1526
 
1527
  fprintf (asm_out_file, "// picoChip ASM file\n");
1528
  fprintf (asm_out_file, "//.file \"%s\"\n", main_input_filename);
1529
 
1530
  fprintf (asm_out_file, "// Has byte access: %s\n",
1531
           (TARGET_HAS_BYTE_ACCESS ? "Yes" : "No"));
1532
 
1533
  if (TARGET_HAS_MUL_UNIT)
1534
    fprintf (asm_out_file, "// Has multiply: Yes (Multiply unit)\n");
1535
  else if (TARGET_HAS_MAC_UNIT)
1536
    fprintf (asm_out_file, "// Has multiply: Yes (Mac unit)\n");
1537
  else
1538
    fprintf (asm_out_file, "// Has multiply: No\n");
1539
 
1540
  /* Variable tracking should be run after all optimizations which change order
1541
     of insns.  It also needs a valid CFG.  This can't be done in
1542
     picochip_override_options, because flag_var_tracking is finalized after
1543
     that.  */
1544
  picochip_flag_var_tracking = flag_var_tracking;
1545
  flag_var_tracking = 0;
1546
}
1547
 
1548
/* Output the end of an ASM file. */
1549
void
1550
picochip_asm_file_end (void)
1551
{
1552
  /* Include a segment end to make it easy for PERL scripts to grab
1553
     segments. This is now done by assembler*/
1554
 
1555
  fprintf (asm_out_file, "// End of picoChip ASM file\n");
1556
 
1557
}
1558
 
1559
/* Output frame debug information to the given stream. */
1560
static void
1561
picochip_output_frame_debug (FILE * file)
1562
{
1563
  int i = 0;
1564
 
1565
  if (current_function_is_leaf)
1566
    fprintf (file, "\t\t// Leaf function\n");
1567
  else
1568
    fprintf (file, "\t\t// Non-leaf function\n");
1569
 
1570
  if (picochip_can_eliminate_link_sp_save ())
1571
    fprintf (file, "\t\t// Link/fp save/restore can be eliminated\n");
1572
 
1573
  if (cfun->static_chain_decl != NULL)
1574
    fprintf (file, "\t\t// Static chain in use\n");
1575
 
1576
  fprintf (file, "\t\t// Incoming argument size: %d bytes\n",
1577
           picochip_arg_area_size_in_bytes ());
1578
  fprintf (file, "\t\t// Incoming arg offset: %d\n",
1579
           picochip_arg_area_byte_offset ());
1580
  fprintf (file, "\t\t// Pretend arg size: %d\n",
1581
           picochip_pretend_arg_area_size ());
1582
  fprintf (file, "\t\t// Pretend arg offset (ARGP): %d\n",
1583
           picochip_pretend_arg_area_byte_offset ());
1584
  fprintf (file, "\t\t// Special reg area size: %d bytes\n",
1585
           picochip_special_save_area_size_in_bytes ());
1586
  fprintf (file, "\t\t// Special reg area offset: %d\n",
1587
           picochip_special_save_area_byte_offset ());
1588
 
1589
  /* Output which registers are saved. */
1590
  fprintf (file, "\t\t// Saved regs: ");
1591
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1592
    {
1593
      if (picochip_reg_needs_saving (i))
1594
        fprintf (file, "%s ", picochip_regnames[i]);
1595
    }
1596
  fprintf (file, "\t\t\n");
1597
 
1598
  fprintf (file, "\t\t// Save area size: %d bytes\n",
1599
           picochip_save_area_size_in_bytes ());
1600
  fprintf (file, "\t\t// Save area offset: %d\n",
1601
           picochip_save_area_byte_offset ());
1602
 
1603
  fprintf (file, "\t\t// Frame size: %ld bytes\n", get_frame_size ());
1604
  fprintf (file, "\t\t// Frame offset (FP): %d\n",
1605
           picochip_frame_byte_offset ());
1606
 
1607
  fprintf (file, "\t\t// Outgoing argument area size: %d bytes\n",
1608
           crtl->outgoing_args_size);
1609
 
1610
}
1611
 
1612
/* Output picoChip function prologue. This contains human-readable
1613
   information about the function. */
1614
void
1615
picochip_function_prologue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1616
{
1617
  /* Get the function's name, as described by its RTL.  This may be
1618
     different from the DECL_NAME name used in the source file.  The
1619
     real declaration name must be used, to ensure that the prologue
1620
     emits the right information for the linker. */
1621
  rtx x;
1622
  const char *fnname;
1623
  x = DECL_RTL (current_function_decl);
1624
  gcc_assert (MEM_P (x));
1625
  x = XEXP (x, 0);
1626
  gcc_assert (GET_CODE (x) == SYMBOL_REF);
1627
  fnname = XSTR (x, 0);
1628
 
1629
  /* Note that the name of the function is given in the &_%s
1630
     form. This matches the name of the function as used in labels,
1631
     and function calls, and enables processCallGraph to match
1632
     function calls to the name of the function, as defined here. */
1633
  fprintf (file, "// picoChip Function Prologue : &_%s = %d bytes\n",
1634
           fnname, picochip_arg_area_byte_offset ());
1635
 
1636
  picochip_output_frame_debug (file);
1637
  fprintf (file, "\n");
1638
 
1639
}
1640
 
1641
/* Output picoChip function epilogue. */
1642
void
1643
picochip_function_epilogue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1644
{
1645
 
1646
  rtx x;
1647
  const char *fnname;
1648
  x = DECL_RTL (current_function_decl);
1649
  gcc_assert (MEM_P (x));
1650
  x = XEXP (x, 0);
1651
  gcc_assert (GET_CODE (x) == SYMBOL_REF);
1652
  fnname = XSTR (x, 0);
1653
  fprintf (file, "\n// picoChip Function Epilogue : %s\n\n",
1654
           fnname);
1655
}
1656
 
1657
/* Manipulate the asm output. Some machines only execute the code when
1658
   there is actually a chance of needing it (e.g., FRV doesn't execute
1659
   it if the scheduling pass wasn't used). We always execute it,
1660
   simple to ensure that it is exercised more often, and bugs are more
1661
   likely to be found.
1662
 
1663
   This function's prime reason for existence is to insert the VLIW
1664
   separators where appropriate. The separators must be inserted
1665
   before any comments which appear at the end of the file.
1666
 
1667
*/
1668
const char *
1669
picochip_asm_output_opcode (FILE * f, const char *ptr)
1670
{
1671
  int c;
1672
 
1673
  /* Flag to specify when a VLIW continuation has been inserted onto
1674
     the line. Continuations are either inserted before any comments,
1675
     or before the end of the line is reached. The flag ensures that
1676
     we don't insert continuations twice (i.e., at the comment and the
1677
     end of line). */
1678
  int continuation_inserted = 0;
1679
 
1680
  /* If the instruction uses multiple lines (i.e., a new line
1681
     character appears in the opcode), then ensure that no attempt is
1682
     made to pack it into a VLIW. */
1683
  if (strchr (ptr, '\n') != NULL && picochip_vliw_continuation)
1684
    internal_error
1685
      ("picochip_asm_output_opcode - Found multiple lines in VLIW packet %s\n",
1686
       ptr);
1687
 
1688
 
1689
  /* If a delay slot is pending, output the directive to the assembler
1690
     before the instruction. */
1691
  if (picochip_is_delay_slot_pending)
1692
    {
1693
      picochip_is_delay_slot_pending = 0;
1694
      fputs ("=->\t", f);
1695
    }
1696
 
1697
  /* Keep going for entire opcode. All substitution performed ourselves. */
1698
  while (*ptr)
1699
    {
1700
      c = *ptr++;
1701
 
1702
      /* Determine whether a VLIW continuation must be inserted before
1703
         any comments, or the end of the opcode. A flag is set to show
1704
         that we have inserted a continuation on this line, so that we
1705
         don't try to insert another continuation when the end of the
1706
         opcode is reached. The only other case for a continuation
1707
         might have been a newline, but these aren't allowed in
1708
         conjunction with VLIW continuations (see above code). */
1709
      if (picochip_vliw_continuation &&
1710
          !continuation_inserted &&
1711
          ((c == '/' && (*ptr == '/')) || *ptr == '\0'))
1712
        {
1713
          fprintf (f, "\\ ");
1714
          continuation_inserted = 1;
1715
        }
1716
 
1717
      /* Detect an explicit VLIW separator. */
1718
      if (c == '%' && (*ptr == '|'))
1719
        {
1720
          fprintf (f, "\\");
1721
          ptr++;
1722
        }
1723
      /* Detect the need for an ALU id operand. */
1724
      else if (c == '%' && (*ptr == '#'))
1725
        {
1726
          fputc (picochip_get_vliw_alu_id (), f);
1727
 
1728
          if (TARGET_DEBUG)
1729
            printf ("Generated ALU char at %s for insn %d\n", ptr,
1730
                    INSN_UID (picochip_current_prescan_insn));
1731
 
1732
          /* Skip past unwanted # */
1733
          ptr++;
1734
        }
1735
      /* Detect the need for branch delay slot. */
1736
      else if (c == '%' && (*ptr == '>'))
1737
        {
1738
          /* Only emit delay slots (NOP's, or otherwise) when delay
1739
           * slot scheduling has actually been enabled, otherwise VLIW
1740
           * scheduling and delay slot scheduling output combine to
1741
           * produce nasty effects. */
1742
          if (flag_delayed_branch)
1743
            {
1744
              if (dbr_sequence_length () == 0)
1745
                fputs ("\n=->\tNOP", f);
1746
              else
1747
                picochip_is_delay_slot_pending = 1;
1748
            }
1749
 
1750
          /* Skip past unwanted > */
1751
          ptr++;
1752
        }
1753
      /* Detect any %digit specifiers. */
1754
      else if (c == '%' && (*ptr >= '0' && *ptr <= '9'))
1755
        {
1756
          c = atoi (ptr);
1757
          picochip_print_operand (f, recog_data.operand[c], 0);
1758
          while ((c = *ptr) >= '0' && c <= '9')
1759
            ptr++;
1760
        }
1761
      /* Detect any %letterdigit specifiers. */
1762
      else if (c == '%' && ((*ptr >= 'a' && *ptr <= 'z')
1763
                            || (*ptr >= 'A' && *ptr <= 'Z')))
1764
        {
1765
          int letter = *ptr++;
1766
 
1767
          c = atoi (ptr);
1768
 
1769
          switch (letter)
1770
            {
1771
            case 'l':
1772
              output_asm_label (recog_data.operand[c]);
1773
              break;
1774
 
1775
            case 'a':
1776
              output_address (recog_data.operand[c]);
1777
              break;
1778
 
1779
            default:
1780
              picochip_print_operand (f, recog_data.operand[c], letter);
1781
            }
1782
 
1783
          while ((c = *ptr) >= '0' && c <= '9')
1784
            ptr++;
1785
        }
1786
      else if (c == '%')
1787
        internal_error
1788
          ("picochip_asm_output_opcode - can't output unknown operator %c\n",
1789
           *ptr);
1790
      else
1791
        fputc (c, f);
1792
    }
1793
 
1794
  /* Reached the end of the packet. If any labels were deferred
1795
     during output, emit them now. */
1796
  if (!picochip_vliw_continuation)
1797
    {
1798
      if (picochip_current_vliw_state.num_cfi_labels_deferred != 0)
1799
        {
1800
          fprintf (f, "\n");
1801
          assemble_name (f, picochip_current_vliw_state.cfi_label_name[0]);
1802
          fprintf (f, "=");
1803
          if (picochip_current_vliw_state.num_cfi_labels_deferred == 2)
1804
          {
1805
            fprintf (f, "\n");
1806
            assemble_name (f, picochip_current_vliw_state.cfi_label_name[1]);
1807
            fprintf (f, "=");
1808
          }
1809
        }
1810
 
1811
      if (strlen (picochip_current_vliw_state.lm_label_name) != 0)
1812
        {
1813
          fprintf (f, "\n");
1814
          assemble_name (f, picochip_current_vliw_state.lm_label_name);
1815
          fprintf (f, "=");
1816
        }
1817
    }
1818
 
1819
  /* Output an end-of-packet marker if requested. */
1820
  if (!picochip_vliw_continuation &&
1821
      TARGET_DEBUG && picochip_schedule_type == DFA_TYPE_SPEED)
1822
    fprintf (f, "\n\t//-------------- End of VLIW packet -----------------");
1823
 
1824
  return ptr;
1825
}
1826
 
1827
/* Function RTL expansion. */
1828
 
1829
/* Expand the prologue into RTL. */
1830
void
1831
picochip_expand_prologue (void)
1832
{
1833
  int stack_adjustment = 0;
1834
  int special_save_offset = 0;
1835
  int general_save_offset = 0;
1836
  int reg_save_offset = 0;
1837
  int i = 0;
1838
 
1839
  stack_adjustment = picochip_arg_area_byte_offset ();
1840
  general_save_offset =
1841
    -(stack_adjustment - picochip_save_area_byte_offset ());
1842
  special_save_offset =
1843
    -(stack_adjustment - picochip_special_save_area_byte_offset ());
1844
 
1845
  /* Save the link registers. We could try to save just one register
1846
     here. This would reduce the amount of stack space required.
1847
     There hasnt been a good reason to do that so far. */
1848
  if (!picochip_can_eliminate_link_sp_save ())
1849
    picochip_emit_save_register (gen_rtx_REG (SImode, LINK_REGNUM),
1850
                                 special_save_offset);
1851
 
1852
  /* Save callee-save registers. */
1853
  reg_save_offset = 0;
1854
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1855
    {
1856
      if (picochip_reg_needs_saving (i))
1857
        {
1858
 
1859
          /* If this register is an even numbered register, and the
1860
             next register also needs to be saved, use a SImode save,
1861
             which does both in one instruction. Note that a special
1862
             check is performed to ensure that the double word aligned
1863
             store is valid (e.g., it is possible that r6, r8, r9 need
1864
             to be saved, in which case once r6 has been saved, the
1865
             stored offset is no longer aligned, and an STL/LDL
1866
             instruction becomes invalid). Alternately, we could store all
1867
             aligned registers first and then save the single one(s). */
1868
          if ((i % 2 == 0) &&
1869
              picochip_reg_needs_saving (i + 1) &&
1870
              picochip_is_aligned (reg_save_offset, LONG_TYPE_SIZE))
1871
            {
1872
              picochip_emit_save_register (gen_rtx_REG (SImode, i),
1873
                                           general_save_offset +
1874
                                           reg_save_offset);
1875
              reg_save_offset += 2 * UNITS_PER_WORD;
1876
              i++;
1877
            }
1878
          else
1879
            {
1880
              picochip_emit_save_register (gen_rtx_REG (HImode, i),
1881
                                           general_save_offset +
1882
                                           reg_save_offset);
1883
              reg_save_offset += UNITS_PER_WORD;
1884
            }
1885
        }
1886
 
1887
    }
1888
 
1889
  /* Emit a stack adjustment where required. */
1890
  if (stack_adjustment != 0)
1891
    picochip_emit_stack_allocate (stack_adjustment);
1892
 
1893
  /* If this function uses varadic arguments, write any unnamed
1894
     registers to the stack. */
1895
  if (cfun->stdarg)
1896
    {
1897
      int stdarg_offset = picochip_pretend_arg_area_byte_offset ();
1898
 
1899
      /* Sanity check. The pretend argument offset should be 32-bit aligned. */
1900
      gcc_assert(picochip_pretend_arg_area_byte_offset () % 4 == 0);
1901
 
1902
      picochip_emit_save_register (gen_rtx_REG (SImode, 0), stdarg_offset);
1903
      picochip_emit_save_register (gen_rtx_REG (SImode, 2),
1904
                                   stdarg_offset + 4);
1905
      picochip_emit_save_register (gen_rtx_REG (SImode, 4),
1906
                                   stdarg_offset + 8);
1907
 
1908
    }
1909
 
1910
}
1911
 
1912
/* Expand the epilogue into RTL. */
1913
void
1914
picochip_expand_epilogue (int is_sibling_call ATTRIBUTE_UNUSED)
1915
{
1916
  int stack_adjustment = 0;
1917
  int special_save_offset = 0;
1918
  int general_save_offset = 0;
1919
  int reg_save_offset = 0;
1920
  int i = 0;
1921
  int use_link_fp_restore_stack_adjust = 0;      /* Default to using an explicit
1922
                                                   stack restore. */
1923
 
1924
  stack_adjustment = picochip_arg_area_byte_offset ();
1925
  general_save_offset =
1926
    -(stack_adjustment - picochip_save_area_byte_offset ());
1927
  special_save_offset =
1928
    -(stack_adjustment - picochip_special_save_area_byte_offset ());
1929
 
1930
  /* Emit a stack adjustment where required. */
1931
  if (stack_adjustment != 0)
1932
    {
1933
      /* If the link/fp is already being restored, and the offset to
1934
         their save location is small enough, don't bother adjusting
1935
         the stack explicitly. */
1936
      if (picochip_special_save_area_byte_offset () < 512 &&
1937
          !picochip_can_eliminate_link_sp_save ())
1938
        use_link_fp_restore_stack_adjust = 1;
1939
      else
1940
        /* Explicitly restore the stack. */
1941
        picochip_emit_stack_allocate (-stack_adjustment);
1942
    }
1943
 
1944
  /* Restore the Link/FP registers. Only save the link register? */
1945
  if (!picochip_can_eliminate_link_sp_save ())
1946
    {
1947
      if (use_link_fp_restore_stack_adjust)
1948
        picochip_emit_restore_register (gen_rtx_REG (SImode, LINK_REGNUM),
1949
                                        picochip_special_save_area_byte_offset
1950
                                        ());
1951
      else
1952
        picochip_emit_restore_register (gen_rtx_REG (SImode, LINK_REGNUM),
1953
                                        special_save_offset);
1954
    }
1955
 
1956
  /* Restore callee-save registers. */
1957
  reg_save_offset = 0;
1958
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1959
    {
1960
      if (picochip_reg_needs_saving (i))
1961
        {
1962
 
1963
          /* If this register is an even numbered register, and the
1964
             next register also needs to be saved, use a SImode save,
1965
             which does both in one instruction. Note that a special
1966
             check is performed to ensure that the double word aligned
1967
             store is valid (e.g., it is possible that r6, r8, r9 need
1968
             to be saved, in which case once r6 has been saved, the
1969
             stored offset is no longer aligned, and an STL/LDL
1970
             instruction becomes invalid). We could store all aligned
1971
             registers first, and then save the single one(s). */
1972
          if ((i % 2 == 0) &&
1973
              picochip_reg_needs_saving (i + 1) &&
1974
              picochip_is_aligned (reg_save_offset, LONG_TYPE_SIZE))
1975
            {
1976
              picochip_emit_restore_register (gen_rtx_REG (SImode, i),
1977
                                              general_save_offset +
1978
                                              reg_save_offset);
1979
              reg_save_offset += 2 * UNITS_PER_WORD;
1980
              i++;
1981
            }
1982
          else
1983
            {
1984
              picochip_emit_restore_register (gen_rtx_REG (HImode, i),
1985
                                              general_save_offset +
1986
                                              reg_save_offset);
1987
              reg_save_offset += UNITS_PER_WORD;
1988
            }
1989
        }
1990
 
1991
    }
1992
 
1993
  /* Emit a return instruction, which matches a (parallel
1994
     [(return) (use r12)]) */
1995
  {
1996
    rtvec p;
1997
    p = rtvec_alloc (2);
1998
 
1999
    RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
2000
    RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
2001
                                    gen_rtx_REG (Pmode, LINK_REGNUM));
2002
    emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
2003
  }
2004
 
2005
}
2006
 
2007
/* Assembly instruction output. */
2008
 
2009
/* Test whether the given branch instruction is short, or long. Short
2010
 * branches are equivalent to real branches, and may be DFA
2011
 * scheduled. Long branches expand to a macro which is handled by the
2012
 * elaborator, and cannot be scheduled. Occasionally, the branch
2013
 * shortening pass, which is run after DFA scheduling, will change the
2014
 * code layout and cause the short branch to be reverted into a long
2015
 * branch. Instead of having to fix this up by emitting new assembly,
2016
 * the short branch is emitted anyway. There is plenty of slack in the
2017
 * calculation of long and short branches (10-bit offset, but only
2018
 * 9-bits used in computation), so there is enough slack for this to
2019
 * be safe. */
2020
static int
2021
picochip_is_short_branch (rtx insn)
2022
{
2023
  int isRealShortBranch = (get_attr_length(insn) == SHORT_BRANCH_LENGTH);
2024
 
2025
  return (isRealShortBranch ||
2026
          (!isRealShortBranch &&
2027
           picochip_current_vliw_state.num_insns_in_packet > 1));
2028
}
2029
 
2030
/* Output a compare-and-branch instruction (matching the cbranch
2031
   pattern). */
2032
const char *
2033
picochip_output_cbranch (rtx operands[])
2034
{
2035
 
2036
  if (HImode != GET_MODE (operands[1]) ||
2037
      (HImode != GET_MODE (operands[2]) &&
2038
       GET_CODE (operands[2]) != CONST_INT))
2039
    {
2040
      internal_error ("%s: At least one operand can't be handled",
2041
                      __FUNCTION__);
2042
    }
2043
 
2044
  /* Use the type of comparison to output the appropriate condition
2045
     test. */
2046
  switch (GET_CODE (operands[0]))
2047
    {
2048
    case NE:
2049
      return ("// if (%1 != %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPNE %l3");
2050
 
2051
    case EQ:
2052
      return ("// if (%1 == %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPEQ %l3");
2053
 
2054
    case LE:
2055
      /* Reverse the operand order to be GE */
2056
      return ("// if (%1 <= %2) goto %l3\n\tSUB.%# %2,%1,r15\n\tJMPGE %l3");
2057
 
2058
    case LEU:
2059
      /* Reverse operand order of GEU. */
2060
      return ("// if (%1 <= %2) goto %l3\n\tSUB.%# %2,%1,r15\n\tJMPHS %l3");
2061
 
2062
    case GE:
2063
      return ("// if (%1 >= %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPGE %l3");
2064
 
2065
    case GEU:
2066
      return ("// if (%1 >= %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPHS %l3");
2067
 
2068
    case LT:
2069
      return ("// if (%1 < %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPLT %l3");
2070
 
2071
    case LTU:
2072
      return ("// if (%1 <{U} %2) goto %l3\n\tSUB.%# %1,%2,r15\n\tJMPLO %l3");
2073
 
2074
    case GT:
2075
      /* Reversed operand version of LT. */
2076
      return ("// if (%1 > %2) goto %l3\n\tSUB.%# %2,%1,r15\n\tJMPLT %l3");
2077
 
2078
    case GTU:
2079
      /* Reverse an LTU. */
2080
      return ("// if (%1 >{U} %2) goto %l3\n\tSUB.%# %2,%1,r15\n\tJMPLO %l3");
2081
 
2082
    default:
2083
      gcc_unreachable();
2084
    }
2085
}
2086
 
2087
/* Output a compare-and-branch instruction (matching the cbranch
2088
   pattern). This function is current unused since the cbranch
2089
   split is disabled. The function is kept around so we can use
2090
   it when we understand how to do cbranch split safely. */
2091
const char *
2092
picochip_output_compare (rtx operands[])
2093
{
2094
 
2095
  if (HImode != GET_MODE (operands[1]) ||
2096
      (HImode != GET_MODE (operands[2]) &&
2097
       GET_CODE (operands[2]) != CONST_INT))
2098
    {
2099
      internal_error ("%s: At least one operand can't be handled",
2100
                      __FUNCTION__);
2101
    }
2102
 
2103
  /* Use the type of comparison to output the appropriate condition
2104
     test. */
2105
  int code = GET_CODE (operands[0]);
2106
  switch (code)
2107
    {
2108
    case NE:
2109
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2110
 
2111
    case EQ:
2112
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2113
 
2114
    case LE:
2115
      /* Reverse the operand order to be GE */
2116
      return ("SUB.%# %2,%1,r15\t// CC := (%0)");
2117
 
2118
    case LEU:
2119
      /* Reverse operand order of GEU. */
2120
      return ("SUB.%# %2,%1,r15\t// CC := (%0)");
2121
 
2122
    case GE:
2123
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2124
 
2125
    case GEU:
2126
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2127
 
2128
    case LT:
2129
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2130
 
2131
    case LTU:
2132
      return ("SUB.%# %1,%2,r15\t// CC := (%0)");
2133
 
2134
    case GT:
2135
      /* Reversed operand version of LT. */
2136
      return ("SUB.%# %2,%1,r15\t// CC := (%0)");
2137
 
2138
    case GTU:
2139
      /* Reverse an LTU. */
2140
      return ("SUB.%# %2,%1,r15\t// CC := (%0)");
2141
 
2142
    default:
2143
      gcc_unreachable();
2144
    }
2145
}
2146
 
2147
/* Output the branch insn part of a compare-and-branch split. */
2148
const char *
2149
picochip_output_branch (rtx operands[], rtx insn)
2150
{
2151
 
2152
  int code = GET_CODE(operands[2]);
2153
  if (picochip_is_short_branch (insn))
2154
    {
2155
      /* Short branches can be output directly using the
2156
         appropriate instruction. */
2157
      switch (code)
2158
        {
2159
        case NE:
2160
          return ("BNE %l0 %>");
2161
        case EQ:
2162
          return ("BEQ %l0 %>");
2163
        case LE:
2164
          return ("BGE %l0 %>");
2165
        case LEU:
2166
          return ("BHS %l0 %>");
2167
        case GE:
2168
          return ("BGE %l0 %>");
2169
        case GEU:
2170
          return ("BHS %l0 %>");
2171
        case LT:
2172
          return ("BLT %l0 %>");
2173
        case LTU:
2174
          return ("BLO %l0 %>");
2175
        case GT:
2176
          return ("BLT %l0 %>");
2177
        case GTU:
2178
          return ("BLO %l0 %>");
2179
        default:
2180
          internal_error ("Unknown short branch in %s (type %d)\n",
2181
                          __FUNCTION__, (int) INTVAL (operands[1]));
2182
          return "UNKNOWN_BRANCH";
2183
        }
2184
    }
2185
  else
2186
    {
2187
      /* Long branches result in the emission of a special
2188
         instruction, which the assembler expands into a suitable long
2189
         branch. */
2190
 
2191
      /* Use the type of comparison to output the appropriate condition
2192
         test. */
2193
      switch (code)
2194
        {
2195
        case NE:
2196
          return ("JMPNE %l0 %>");
2197
        case EQ:
2198
          return ("JMPEQ %l0 %>");
2199
        case LE:
2200
          return ("JMPGE %l0 %>");
2201
        case LEU:
2202
          return ("JMPHS %l0 %>");
2203
        case GE:
2204
          return ("JMPGE %l0 %>");
2205
        case GEU:
2206
          return ("JMPHS %l0 %>");
2207
        case LT:
2208
          return ("JMPLT %l0 %>");
2209
        case LTU:
2210
          return ("JMPLO %l0 %>");
2211
        case GT:
2212
          return ("JMPLT %l0 %>");
2213
        case GTU:
2214
          return ("JMPLO %l0 %>");
2215
 
2216
        default:
2217
          internal_error ("Unknown long branch in %s (type %d)\n",
2218
                          __FUNCTION__, (int) INTVAL (operands[1]));
2219
          return "UNKNOWN_BRANCH";
2220
        }
2221
 
2222
    }
2223
}
2224
 
2225
/* Output a jump instruction. */
2226
const char *
2227
picochip_output_jump (rtx insn)
2228
{
2229
  if (picochip_is_short_branch (insn))
2230
    return "BRA %l0%>";
2231
  else
2232
    return "JMPRA %l0%>";
2233
}
2234
 
2235
const char *
2236
picochip_output_put_array (int alternative, rtx operands[])
2237
{
2238
  /* Local output buffer. */
2239
  char buf[256];
2240
 
2241
  int portArraySize = INTVAL(operands[1]);
2242
  int portBaseIndex = INTVAL(operands[2]);
2243
 
2244
  if (alternative == 0)
2245
    {
2246
      sprintf (buf, "// Array put\n\tadd.0 [lsl %%0,2],&__commTable_put_%d_%d,lr\n\tjl (lr)",
2247
               portArraySize, portBaseIndex);
2248
      output_asm_insn (buf, operands);
2249
    }
2250
  else if (alternative == 1)
2251
    {
2252
      /* Constant port id. Emit a real instruction. */
2253
      int portIndex = INTVAL(operands[0]) + portBaseIndex;
2254
      if (portIndex < portBaseIndex ||
2255
          portIndex >= (portBaseIndex + portArraySize))
2256
        {
2257
          error ("PUT uses port array index %d, which is out of range [%d..%d)",
2258
                 portIndex, portBaseIndex, portBaseIndex + portArraySize);
2259
        }
2260
      sprintf(buf, "PUT R[0:1],%d", portIndex);
2261
      output_asm_insn (buf, operands);
2262
    }
2263
  else
2264
    gcc_unreachable();
2265
 
2266
  /* Both alternatives output the insn directly. */
2267
  return "";
2268
}
2269
 
2270
const char *picochip_output_get_array (int alternative, rtx operands[])
2271
{
2272
  /* Local output buffer. */
2273
  char buf[256];
2274
 
2275
  int portArraySize = INTVAL(operands[1]);
2276
  int portBaseIndex = INTVAL(operands[2]);
2277
 
2278
  if (alternative == 0)
2279
    {
2280
      sprintf (buf, "// Array get\n\tadd.0 [lsl %%0,2],&__commTable_get_%d_%d,lr\n\tjl (lr)",
2281
               portArraySize, portBaseIndex);
2282
      output_asm_insn (buf, operands);
2283
    }
2284
  else if (alternative == 1)
2285
    {
2286
      /* Constant port id. Emit a real instruction. */
2287
      int portIndex = INTVAL(operands[0]) + portBaseIndex;
2288
      if (portIndex < portBaseIndex ||
2289
          portIndex >= (portBaseIndex + portArraySize))
2290
        {
2291
          error ("GET uses port array index %d, which is out of range [%d..%d)",
2292
                 portIndex, portBaseIndex, portBaseIndex + portArraySize);
2293
        }
2294
      sprintf(buf, "GET %d,R[0:1]", portIndex);
2295
      output_asm_insn (buf, operands);
2296
    }
2297
  else
2298
    gcc_unreachable();
2299
 
2300
  /* Both alternatives output the insn directly. */
2301
  return "";
2302
}
2303
 
2304
const char *picochip_output_testport_array (int alternative, rtx operands[])
2305
{
2306
  /* Local output buffer. */
2307
  char buf[256];
2308
 
2309
  int portArraySize = INTVAL(operands[2]);
2310
  int portBaseIndex = INTVAL(operands[3]);
2311
 
2312
  if (alternative == 0)
2313
    {
2314
      sprintf (buf, "// Array tstport\n\tadd.0 [lsl %%1,2],&__commTable_tstport_%d_%d,lr\n\tjl (lr)\n=->\tcopy.0 0,%%0\n\tcopyeq 1,%%0",
2315
               portArraySize, portBaseIndex);
2316
      output_asm_insn (buf, operands);
2317
    }
2318
  else if (alternative == 1)
2319
    {
2320
      /* Constant port id. Emit a real instruction. */
2321
      int portIndex = INTVAL(operands[1]) + portBaseIndex;
2322
      if (portIndex < portBaseIndex ||
2323
          portIndex >= (portBaseIndex + portArraySize))
2324
        {
2325
          error ("PUT uses port array index %d, which is out of range [%d..%d)",
2326
                 portIndex, portBaseIndex, portBaseIndex + portArraySize);
2327
        }
2328
      sprintf(buf, "copy.1 0,%%0 %%| TSTPORT %d\n\tcopyeq 1,%%0", portIndex);
2329
      output_asm_insn (buf, operands);
2330
    }
2331
  else
2332
    gcc_unreachable();
2333
 
2334
  /* Both alternatives output the insn directly. */
2335
  return "";
2336
}
2337
 
2338
/* Output a comparison operand as a symbol (e.g., >). */
2339
static void
2340
picochip_print_comparison (FILE * file, rtx operand, int letter)
2341
{
2342
 
2343
  if (letter == 'i')
2344
    {
2345
      /* Output just the comparison symbol. */
2346
      switch (GET_CODE (operand))
2347
        {
2348
        case NE:
2349
          fprintf (file, "!=");
2350
          break;
2351
        case EQ:
2352
          fprintf (file, "==");
2353
          break;
2354
        case GE:
2355
          fprintf (file, ">=");
2356
          break;
2357
        case GEU:
2358
          fprintf (file, ">={U}");
2359
          break;
2360
        case LT:
2361
          fprintf (file, "<");
2362
          break;
2363
        case LTU:
2364
          fprintf (file, "<{U}");
2365
          break;
2366
        case LE:
2367
          fprintf (file, "<=");
2368
          break;
2369
        case LEU:
2370
          fprintf (file, "<={U}");
2371
          break;
2372
        case GT:
2373
          fprintf (file, ">");
2374
          break;
2375
        case GTU:
2376
          fprintf (file, ">{U}");
2377
          break;
2378
        default:
2379
          gcc_unreachable();
2380
        }
2381
    }
2382
  else
2383
    {
2384
      /* Output the comparison formatted as operand,symbol,operand */
2385
      rtx op0 = XEXP (operand, 0);
2386
      rtx op1 = XEXP (operand, 1);
2387
 
2388
      picochip_print_operand (file, op0, 0);
2389
      picochip_print_comparison (file, operand, 'i');
2390
      picochip_print_operand (file, op1, 0);
2391
    }
2392
}
2393
 
2394
/* This function generates a memory address operand in the given
2395
   mode.  That is, if the address contains a constant offset, then the
2396
   offset is divided by the required mode size to compute the
2397
   mode specific offset.  By default, picochip_print_operand_address calls
2398
   this function using the natural mode of the operand, but special
2399
   operand codes can be used to invoke the computation using an
2400
   unnatural mode (e.g., compute the HI aligned address of an SI mode
2401
   address). */
2402
static void
2403
picochip_print_memory_address (FILE * file, rtx operand,
2404
                               enum machine_mode mode)
2405
{
2406
  rtx address = XEXP (operand, 0);
2407
 
2408
  /* Sanity check. */
2409
  if (MEM != GET_CODE (operand))
2410
    fatal_insn ("picochip_print_memory_address - Operand isn't memory based",
2411
                operand);
2412
 
2413
  if (TARGET_DEBUG)
2414
    {
2415
      printf ("picochip_print_memory_address: ");
2416
      print_rtl (stdout, operand);
2417
      printf ("\n");
2418
    }
2419
 
2420
  switch (GET_CODE (address))
2421
    {
2422
    case PLUS:
2423
      {
2424
        /* Grab the address components. */
2425
        rtx base = XEXP (address, 0);
2426
        rtx offset = XEXP (address, 1);
2427
 
2428
        /* Only handle reg+const addresses */
2429
        if (REG == GET_CODE (base) && CONST_INT == GET_CODE (offset))
2430
          {
2431
            /* Sanity check.  If an FP+offset address is given, ensure
2432
               that the offset lies within the given frame, or a lower
2433
               frame. */
2434
            if (REGNO (base) == STACK_POINTER_REGNUM )
2435
              gcc_assert (INTVAL (offset) <= (picochip_arg_area_byte_offset () +
2436
                          crtl->args.size));
2437
 
2438
            /* Print the base register - identical for all modes. */
2439
            fprintf (file, "(");
2440
            picochip_print_operand (file, base, 'r');
2441
            fprintf (file, ")");
2442
 
2443
            /* Print the constant offset with compensation for the mode. */
2444
            switch (mode)
2445
              {
2446
              case QImode:
2447
                picochip_print_operand (file, offset, 'Q');
2448
                break;
2449
 
2450
              case HImode:
2451
                picochip_print_operand (file, offset, 'H');
2452
                break;
2453
 
2454
              case SImode:
2455
              case SFmode:
2456
                picochip_print_operand (file, offset, 'S');
2457
                break;
2458
 
2459
              case DImode:
2460
                picochip_print_operand (file, offset, 'D');
2461
                break;
2462
 
2463
              default:
2464
                gcc_unreachable();
2465
              }
2466
 
2467
          }
2468
 
2469
      }
2470
 
2471
      break;
2472
 
2473
    case SYMBOL_REF:
2474
      picochip_print_operand (file, address, 's');
2475
      break;
2476
 
2477
    case CONST:
2478
      {
2479
        rtx inner;
2480
        rtx base;
2481
        rtx offset;
2482
 
2483
        inner = XEXP (address, 0);
2484
 
2485
        /* Sanity check - the CONST memory address must be a base+offset. */
2486
        gcc_assert (PLUS == GET_CODE (inner));
2487
 
2488
        base = XEXP (inner, 0);
2489
        offset = XEXP (inner, 1);
2490
 
2491
        fprintf (file, "&_%s%+d", XSTR (base, 0), XINT (offset, 0));
2492
 
2493
        break;
2494
      }
2495
 
2496
    case REG:
2497
      /* Register operand. Provide a zero offset. */
2498
      fprintf (file, "(");
2499
      picochip_print_operand (file, address, 'r');
2500
      fprintf (file, ")0");
2501
      break;
2502
 
2503
    default:
2504
      gcc_unreachable();
2505
    }
2506
 
2507
}
2508
 
2509
/* Output an operand.  Formatting letters allow particular parts of
2510
   the operand to be output. */
2511
void
2512
picochip_print_operand (FILE * file, rtx operand, int letter)
2513
{
2514
 
2515
  /* Handle special cases. */
2516
  switch (letter)
2517
    {
2518
      /* VLIW continuation, for explicit VLIW sequences. */
2519
    case '|':
2520
      fprintf (file, "\\");
2521
      return;
2522
 
2523
      /* ALU selector.  */
2524
    case '#':
2525
      fputc (picochip_get_vliw_alu_id (), file);
2526
      return;
2527
 
2528
      /* Delay slot specifier. */
2529
    case '>':
2530
      /* This should be handled in asm_output_opcode. */
2531
      gcc_unreachable();
2532
 
2533
      /* Instruction mnemonics (e.g., lshift becomes LSL). */
2534
    case 'I':
2535
      switch (GET_CODE (operand))
2536
        {
2537
        case AND:
2538
          fprintf (file, "AND");
2539
          break;
2540
        case IOR:
2541
          fprintf (file, "OR");
2542
          break;
2543
        case XOR:
2544
          fprintf (file, "XOR");
2545
          break;
2546
        case PLUS:
2547
          fprintf (file, "ADD");
2548
          break;
2549
        case MINUS:
2550
          fprintf (file, "SUB");
2551
          break;
2552
        default:
2553
          gcc_unreachable();
2554
        }
2555
      return;
2556
 
2557
      /* Symbolic instructions (e.g., lshift becomes <<). */
2558
    case 'i':
2559
      switch (GET_CODE (operand))
2560
        {
2561
        case AND:
2562
          fprintf (file, "&");
2563
          break;
2564
        case IOR:
2565
          fprintf (file, "|");
2566
          break;
2567
        case XOR:
2568
          fprintf (file, "^");
2569
          break;
2570
        case PLUS:
2571
          fprintf (file, "+");
2572
          break;
2573
        case MINUS:
2574
          fprintf (file, "-");
2575
          break;
2576
        default:
2577
          fprintf (file, "UNKNOWN_INSN");
2578
          break;
2579
        }
2580
      return;
2581
 
2582
    default:                    /* Not a punctuation character - process as normal. */
2583
      break;
2584
    }
2585
 
2586
  switch (GET_CODE (operand))
2587
    {
2588
    case REG:
2589
      switch (letter)
2590
        {
2591
        case 'R':
2592
          /* Write a range of registers. */
2593
          fprintf (file, "R[%d:%d]", REGNO (operand) + 1, REGNO (operand));
2594
          break;
2595
 
2596
        case 'U':
2597
          /* The upper register of a pair is requested. */
2598
          fprintf (file, "%s", picochip_regnames[REGNO (operand) + 1]);
2599
          break;
2600
 
2601
        case 'L':
2602
          /* The lower register of a pair is requested. Equivalent to the
2603
             default, but included for completeness. */
2604
          fprintf (file, "%s", picochip_regnames[REGNO (operand)]);
2605
          break;
2606
 
2607
        case 'X':
2608
          /* The 3rd register of a DI mode register. */
2609
          fprintf (file, "%s", picochip_regnames[REGNO (operand) + 2]);
2610
          break;
2611
 
2612
        case 'Y':
2613
          /* The 4th register of a DI mode register. */
2614
          fprintf (file, "%s", picochip_regnames[REGNO (operand) + 3]);
2615
          break;
2616
 
2617
        default:
2618
          fprintf (file, "%s", picochip_regnames[REGNO (operand)]);
2619
        }
2620
      break;
2621
 
2622
    case CONST_INT:
2623
      /* A range of letters can be used to format integers.  The
2624
         letters Q/H/S are used to divide the constant by the width of
2625
         QI/HI/SI mode integers in bytes.  The U/L modifiers are used
2626
         to obtain the upper and lower 16-bits of a 32-bit
2627
         constant.  Where possible, signed numbers are used, since
2628
         signed representations of numbers may be more compact (e.g.,
2629
         65535 can be represented as -1, which fits into a small
2630
         constant, whereas 65535 requires a large constant). */
2631
      switch (letter)
2632
        {
2633
        case 'Q':
2634
          fprintf (file, "%ld", INTVAL (operand));
2635
          break;
2636
 
2637
        case 'H':
2638
          fprintf (file, "%ld", INTVAL (operand) / 2);
2639
          break;
2640
 
2641
        case 'S':
2642
          fprintf (file, "%ld", INTVAL (operand) / 4);
2643
          break;
2644
 
2645
        case 'P':
2646
          fprintf (file, "%d", exact_log2 (INTVAL(operand)));
2647
          break;
2648
 
2649
        case 'U':
2650
          fprintf (file, "%hi", (short) ((INTVAL (operand) >> 16) & 0xFFFF));
2651
          break;
2652
 
2653
        case 'L':
2654
          fprintf (file, "%hi", (short) (INTVAL (operand) & 0xFFFF));
2655
          break;
2656
 
2657
        default:
2658
          fprintf (file, "%ld", INTVAL (operand));
2659
          break;
2660
        }
2661
      break;
2662
 
2663
    case CONST_DOUBLE:
2664
      {
2665
        long val;
2666
        REAL_VALUE_TYPE rv;
2667
 
2668
        if (GET_MODE (operand) != SFmode)
2669
          fatal_insn ("Unknown mode in print_operand (CONST_DOUBLE) :",
2670
                      operand);
2671
        REAL_VALUE_FROM_CONST_DOUBLE (rv, operand);
2672
        REAL_VALUE_TO_TARGET_SINGLE (rv, val);
2673
 
2674
        switch (letter)
2675
          {
2676
          case 'U':
2677
            fprintf (file, "%hi", (short) ((val >> 16) & 0xFFFF));
2678
            break;
2679
 
2680
          case 'L':
2681
            fprintf (file, "%hi", (short) (val & 0xFFFF));
2682
            break;
2683
          }
2684
 
2685
        break;
2686
 
2687
      }
2688
 
2689
      /* Output a symbol.  The output format must match that of
2690
         picochip_output_label. */
2691
    case SYMBOL_REF:
2692
      /* Ensure that the symbol is marked as referenced.  Gcc can
2693
         occasionally omit the function bodies when it believes them
2694
         to be unreferenced. */
2695
      if (SYMBOL_REF_DECL (operand))
2696
        mark_decl_referenced (SYMBOL_REF_DECL (operand));
2697
      fprintf (file, "&");
2698
      assemble_name (file, XSTR (operand, 0));
2699
      break;
2700
 
2701
    case LABEL_REF:
2702
      /* This format must match that of picochip_output_label. */
2703
      fprintf (file, "&");
2704
      output_asm_label (operand);
2705
      break;
2706
 
2707
    case MEM:
2708
      {
2709
        rtx addr = XEXP (operand, 0);
2710
 
2711
        switch (letter)
2712
          {
2713
          case 'o':
2714
            if (PLUS != GET_CODE (addr))
2715
              fatal_insn ("Bad address, not (reg+disp):", addr);
2716
            else
2717
              picochip_print_operand (file, XEXP (addr, 1), 0);
2718
            break;
2719
 
2720
          case 'M':
2721
            /* Output a memory address in byte mode notation (i.e., the
2722
               constant address (if any) is the actual byte address. */
2723
            picochip_print_memory_address (file, operand, QImode);
2724
            break;
2725
 
2726
            /* Output a constant offset of the given mode (i.e., divide
2727
               the constant by the number of units in the mode to get the
2728
               constant). */
2729
          case 'Q':
2730
            picochip_print_memory_address (file, operand, QImode);
2731
            break;
2732
 
2733
          case 'H':
2734
            picochip_print_memory_address (file, operand, HImode);
2735
            break;
2736
 
2737
          case 'S':
2738
            picochip_print_memory_address (file, operand, SImode);
2739
            break;
2740
 
2741
          case 'F':
2742
            picochip_print_memory_address (file, operand, SFmode);
2743
            break;
2744
 
2745
          case 'b':
2746
            if (PLUS != GET_CODE (addr))
2747
              fatal_insn ("Bad address, not (reg+disp):", addr);
2748
            else
2749
              picochip_print_operand (file, XEXP (addr, 0), 0);
2750
            break;
2751
 
2752
          /* When the mem operand is (reg + big offset) which cannot
2753
            be represented in an instruction as operand, the compiler
2754
            automatically generates the instruction to put in (reg +
2755
            big offset) into another register. In such cases, it
2756
            returns '0' as the character. This needs to be handled
2757
            as well. */
2758
          case 0:
2759
          case 'r':
2760
            if (REG != GET_CODE (addr))
2761
              fatal_insn ("Bad address, not register:", addr);
2762
            else
2763
              picochip_print_operand (file, addr, 0);
2764
            break;
2765
 
2766
          default:
2767
            fprintf (file, "Unknown mem operand - letter %c ",
2768
                     (char) (letter));
2769
            print_rtl (file, operand);
2770
          }
2771
 
2772
        break;
2773
      }
2774
 
2775
    case CONST:
2776
      {
2777
        rtx const_exp = XEXP (operand, 0);
2778
 
2779
        /* Handle constant offsets to symbol references. */
2780
        if (PLUS == GET_CODE (const_exp) &&
2781
            SYMBOL_REF == GET_CODE (XEXP (const_exp, 0)) &&
2782
            CONST_INT == GET_CODE (XEXP (const_exp, 1)))
2783
          {
2784
 
2785
            picochip_print_operand (file, XEXP (const_exp, 0), 0);
2786
            if (INTVAL (XEXP (const_exp, 1)) >= 0)
2787
              fprintf (file, "+");
2788
            /* else use the - from the operand (i.e., AP-2)) */
2789
 
2790
            picochip_print_operand (file, XEXP (const_exp, 1), letter);
2791
 
2792
          }
2793
      }
2794
      break;
2795
 
2796
 
2797
    case PLUS:
2798
      {
2799
        /* PLUS expressions are of the form (base + offset). Different
2800
           options (analagous to those of memory PLUS expressions) are used
2801
           to extract the base and offset components. */
2802
 
2803
        switch (letter)
2804
          {
2805
          case 'b':
2806
            picochip_print_operand (file, XEXP (operand, 0), 0);
2807
            break;
2808
 
2809
          case 'o':
2810
            picochip_print_operand (file, XEXP (operand, 1), 0);
2811
            break;
2812
 
2813
          default:
2814
 
2815
            /* If the expression is composed entirely of constants,
2816
               evaluate the result.  This should only occur with the
2817
               picoChip specific comms instructions, which are emitted as
2818
               base+offset expressions. */
2819
            if (CONST_INT == GET_CODE (XEXP (operand, 0)) &&
2820
                CONST_INT == GET_CODE (XEXP (operand, 1)))
2821
              {
2822
                HOST_WIDE_INT result = (XINT (XEXP (operand, 0), 0) +
2823
                                        XINT (XEXP (operand, 1), 0));
2824
                fprintf (file, "%ld", result);
2825
              }
2826
            else
2827
              {
2828
                fprintf (file, "(");
2829
                picochip_print_operand (file, XEXP (operand, 0), 0);
2830
                fprintf (file, "+");
2831
                picochip_print_operand (file, XEXP (operand, 1), 0);
2832
                fprintf (file, ")");
2833
              }
2834
          }
2835
 
2836
        break;
2837
      }
2838
 
2839
      /* Comparison operations. */
2840
    case NE:
2841
    case EQ:
2842
    case GE:
2843
    case GEU:
2844
    case LT:
2845
    case LTU:
2846
    case LE:
2847
    case LEU:
2848
    case GT:
2849
    case GTU:
2850
      picochip_print_comparison (file, operand, letter);
2851
      return;
2852
 
2853
    default:
2854
      fprintf (stderr, "Unknown operand encountered in %s\n", __FUNCTION__);
2855
      print_rtl (file, operand);
2856
      break;
2857
 
2858
    }
2859
 
2860
}
2861
 
2862
/* Output an operand address */
2863
void
2864
picochip_print_operand_address (FILE * file, rtx operand)
2865
{
2866
 
2867
  switch (GET_CODE (operand))
2868
    {
2869
 
2870
    case SYMBOL_REF:
2871
      /* This format must match that of picochip_output_label. */
2872
      assemble_name (file, XSTR (operand, 0));
2873
      break;
2874
 
2875
    case CODE_LABEL:
2876
      /* Note  this format must match that of picochip_output_label. */
2877
      fprintf (file, "_L%d", XINT (operand, 5));
2878
      break;
2879
 
2880
    case MEM:
2881
      /* Pass on to a specialised memory address generator. */
2882
      picochip_print_memory_address (file, operand, GET_MODE (operand));
2883
      break;
2884
 
2885
    default:
2886
      gcc_unreachable();
2887
 
2888
    }
2889
 
2890
}
2891
 
2892
 
2893
/* Scheduling functions. */
2894
 
2895
/* Save some of the contents of recog_data. */
2896
static void
2897
picochip_save_recog_data (void)
2898
{
2899
  picochip_saved_which_alternative = which_alternative;
2900
  memcpy (&picochip_saved_recog_data, &recog_data,
2901
          sizeof (struct recog_data));
2902
}
2903
 
2904
/* Restore some of the contents of global variable recog_data. */
2905
static void
2906
picochip_restore_recog_data (void)
2907
{
2908
  which_alternative = picochip_saved_which_alternative;
2909
  memcpy (&recog_data, &picochip_saved_recog_data,
2910
          sizeof (struct recog_data));
2911
}
2912
 
2913
/* Ensure that no var tracking notes are emitted in the middle of a
2914
   three-instruction bundle.  */
2915
static void
2916
reorder_var_tracking_notes (void)
2917
{
2918
  basic_block bb;
2919
  FOR_EACH_BB (bb)
2920
    {
2921
      rtx insn, next;
2922
      rtx queue = NULL_RTX;
2923
 
2924
      for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next)
2925
        {
2926
          next = NEXT_INSN (insn);
2927
 
2928
          if (NONDEBUG_INSN_P (insn))
2929
            {
2930
              /* Emit queued up notes before the first instruction of a bundle.  */
2931
              if (GET_MODE (insn) == TImode)
2932
                {
2933
                  while (queue)
2934
                    {
2935
                      rtx next_queue = PREV_INSN (queue);
2936
                      NEXT_INSN (PREV_INSN(insn)) = queue;
2937
                      PREV_INSN (queue) = PREV_INSN(insn);
2938
                      PREV_INSN (insn) = queue;
2939
                      NEXT_INSN (queue) = insn;
2940
                      queue = next_queue;
2941
                    }
2942
                }
2943
            }
2944
          else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
2945
            {
2946
               rtx prev = PREV_INSN (insn);
2947
               PREV_INSN (next) = prev;
2948
               NEXT_INSN (prev) = next;
2949
               PREV_INSN (insn) = queue;
2950
               queue = insn;
2951
            }
2952
        }
2953
    }
2954
}
2955
 
2956
/* Perform machine dependent operations on the rtl chain INSNS. */
2957
void
2958
picochip_reorg (void)
2959
{
2960
  rtx insn, insn1, vliw_start;
2961
  int vliw_insn_location = 0;
2962
 
2963
  /* We are freeing block_for_insn in the toplev to keep compatibility
2964
     with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
2965
  compute_bb_for_insn ();
2966
 
2967
  if (optimize == 0)
2968
    split_all_insns ();
2969
 
2970
  if (picochip_schedule_type != DFA_TYPE_NONE)
2971
    {
2972
      timevar_push (TV_SCHED2);
2973
 
2974
      /* Process the instruction list, computing the sizes of each
2975
         instruction, and consequently branch distances.  This can
2976
         result in some branches becoming short enough to be treated
2977
         as a real branch instruction, rather than an assembly branch
2978
         macro which may expand into multiple instructions.  The
2979
         benefit of shortening branches is that real branch
2980
         instructions can be properly DFA scheduled, whereas macro
2981
         branches cannot. */
2982
      shorten_branches (get_insns ());
2983
 
2984
      /* Do control and data sched analysis again,
2985
         and write some more of the results to dump file. */
2986
 
2987
      split_all_insns ();
2988
 
2989
      schedule_ebbs ();
2990
 
2991
      timevar_pop (TV_SCHED2);
2992
 
2993
      ggc_collect ();
2994
 
2995
      if (picochip_schedule_type == DFA_TYPE_SPEED)
2996
        {
2997
          /* Whenever a VLIW packet is generated, all instructions in
2998
             that packet must appear to come from the same source
2999
             location.  The following code finds all the VLIW packets,
3000
             and tags their instructions with the location of the first
3001
             instruction from the packet.  Clearly this will result in
3002
             strange behaviour when debugging the code, but since
3003
             debugging and optimisation are being used in conjunction,
3004
             strange behaviour is certain to occur anyway. */
3005
          /* Slight bit of change. If the vliw set contains a branch
3006
             or call instruction, we pick its location.*/
3007
          for (insn = get_insns (); insn; insn = next_insn (insn))
3008
            {
3009
 
3010
              /* If this is the first instruction in the VLIW packet,
3011
                 extract its location. */
3012
              if (GET_MODE (insn) == TImode)
3013
              {
3014
                vliw_start = insn;
3015
                vliw_insn_location = INSN_LOCATOR (insn);
3016
              }
3017
              if (JUMP_P (insn) || CALL_P(insn))
3018
              {
3019
                vliw_insn_location = INSN_LOCATOR (insn);
3020
                for (insn1 = vliw_start; insn1 != insn ; insn1 = next_insn (insn1))
3021
                  INSN_LOCATOR (insn1) = vliw_insn_location;
3022
              }
3023
              /* Tag subsequent instructions with the same location. */
3024
              if (NONDEBUG_INSN_P (insn))
3025
                INSN_LOCATOR (insn) = vliw_insn_location;
3026
            }
3027
        }
3028
 
3029
    }
3030
 
3031
  /* Locate the note marking the end of the function's prologue.  If
3032
     the note appears in the middle of a VLIW packet, move the note to
3033
     the end.  This avoids unpleasant consequences such as trying to
3034
     emit prologue markers (e.g., .loc/.file directives) in the middle
3035
     of VLIW packets. */
3036
  if (picochip_schedule_type == DFA_TYPE_SPEED)
3037
    {
3038
      rtx prologue_end_note = NULL;
3039
      rtx last_insn_in_packet = NULL;
3040
 
3041
      for (insn = get_insns (); insn; insn = next_insn (insn))
3042
        {
3043
          /* The prologue end must be moved to the end of the VLIW packet. */
3044
          if (NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
3045
            {
3046
              prologue_end_note = insn;
3047
              break;
3048
            }
3049
        }
3050
 
3051
      /* Find the last instruction in this packet. */
3052
      for (insn = prologue_end_note; insn; insn = next_real_insn (insn))
3053
        {
3054
          if (GET_MODE (insn) == TImode)
3055
            break;
3056
          else
3057
            last_insn_in_packet = insn;
3058
        }
3059
 
3060
      if (last_insn_in_packet != NULL)
3061
        {
3062
          rtx tmp_note = emit_note_after (NOTE_KIND(prologue_end_note), last_insn_in_packet);
3063
          memcpy(&NOTE_DATA (tmp_note), &NOTE_DATA(prologue_end_note), sizeof(NOTE_DATA(prologue_end_note)));
3064
          delete_insn (prologue_end_note);
3065
        }
3066
    }
3067
  if (picochip_flag_var_tracking)
3068
  {
3069
    timevar_push (TV_VAR_TRACKING);
3070
    variable_tracking_main ();
3071
    /* We also have to deal with variable tracking notes in the middle
3072
       of VLIW packets. */
3073
    reorder_var_tracking_notes();
3074
    timevar_pop (TV_VAR_TRACKING);
3075
  }
3076
}
3077
 
3078
/* Return the ALU character identifier for the current
3079
   instruction.  This will be 0 or 1. */
3080
static char
3081
picochip_get_vliw_alu_id (void)
3082
{
3083
  int attr_type = 0;
3084
 
3085
  /* Always use ALU 0 if VLIW scheduling is disabled. */
3086
  if (picochip_schedule_type != DFA_TYPE_SPEED)
3087
    return '0';
3088
 
3089
  /* Get the attribute type of the instruction.  Note that this can
3090
     ruin the contents of recog_data, so save/restore around the
3091
     call. */
3092
  picochip_save_recog_data ();
3093
  attr_type = get_attr_type (picochip_current_prescan_insn);
3094
  picochip_restore_recog_data ();
3095
 
3096
  if (picochip_current_vliw_state.contains_pico_alu_insn)
3097
    {
3098
 
3099
      /* If this a picoAlu insn? If it is, then stuff it into ALU 0,
3100
         else it must be the other ALU (either basic or nonCc)
3101
         instruction which goes into 1. */
3102
      if (attr_type == TYPE_PICOALU)
3103
        return '0';
3104
      else
3105
        return '1';
3106
 
3107
    }
3108
  else if (picochip_current_vliw_state.contains_non_cc_alu_insn)
3109
    {
3110
      /* Is this the non CC instruction? If it is, then stuff it into
3111
         ALU 1, else it must be a picoAlu or basicAlu, in which case
3112
         it goes into ALU 0. */
3113
      if (attr_type == TYPE_NONCCALU)
3114
        return '1';
3115
      else
3116
        return '0';
3117
    }
3118
  else
3119
    {
3120
      /* No picoAlu/nonCc instructions in use, so purely dependent upon
3121
         whether an ALU instruction has already been scheduled in this
3122
         cycle. */
3123
      switch (picochip_current_vliw_state.num_alu_insns_so_far)
3124
        {
3125
        case 0:
3126
          picochip_current_vliw_state.num_alu_insns_so_far++;
3127
          return '0';
3128
 
3129
        case 1:
3130
          picochip_current_vliw_state.num_alu_insns_so_far++;
3131
          return '1';
3132
 
3133
        default:
3134
          internal_error ("Too many ALU instructions emitted (%d)\n",
3135
                          picochip_current_vliw_state.num_alu_insns_so_far);
3136
          return 'X';
3137
        }
3138
    }
3139
 
3140
}
3141
 
3142
/* Reset any information about the current VLIW packing status. */
3143
static void
3144
picochip_reset_vliw (rtx insn)
3145
{
3146
  rtx local_insn = insn;
3147
 
3148
  /* Nothing to do if VLIW scheduling isn't being used. */
3149
  if (picochip_schedule_type != DFA_TYPE_SPEED)
3150
    return;
3151
 
3152
  if (TARGET_DEBUG)
3153
    printf ("%s on insn %d\n", __FUNCTION__, INSN_UID (insn));
3154
 
3155
  /* Reset. */
3156
  picochip_current_vliw_state.contains_pico_alu_insn = 0;
3157
  picochip_current_vliw_state.contains_non_cc_alu_insn = 0;
3158
  picochip_current_vliw_state.num_alu_insns_so_far = 0;
3159
  picochip_current_vliw_state.num_cfi_labels_deferred = 0;
3160
  picochip_current_vliw_state.lm_label_name[0] = 0;
3161
  picochip_current_vliw_state.num_insns_in_packet = 0;
3162
 
3163
  /* Read through the VLIW packet, classifying the instructions where
3164
     appropriate. */
3165
  local_insn = insn;
3166
  do
3167
    {
3168
      if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn))
3169
        {
3170
          local_insn = NEXT_INSN (local_insn);
3171
          continue;
3172
        }
3173
      else if (!INSN_P (local_insn))
3174
        break;
3175
      else
3176
        {
3177
          /* It is an instruction, but is it ours? */
3178
          if (INSN_CODE (local_insn) != -1)
3179
            {
3180
              int attr_type = 0;
3181
 
3182
              picochip_current_vliw_state.num_insns_in_packet += 1;
3183
 
3184
              /* Is it a picoAlu or nonCcAlu instruction? Note that the
3185
                 get_attr_type function can overwrite the values in
3186
                 the recog_data global, hence this is saved and
3187
                 restored around the call.  Not doing so results in
3188
                 asm_output_opcode being called with a different
3189
                 instruction to final_prescan_insn, which is fatal. */
3190
              picochip_save_recog_data ();
3191
              attr_type = get_attr_type (local_insn);
3192
              picochip_restore_recog_data ();
3193
 
3194
              if (attr_type == TYPE_PICOALU)
3195
                picochip_current_vliw_state.contains_pico_alu_insn = 1;
3196
              if (attr_type == TYPE_NONCCALU)
3197
                picochip_current_vliw_state.contains_non_cc_alu_insn = 1;
3198
 
3199
            }
3200
        }
3201
 
3202
      /* Get the next instruction. */
3203
      local_insn = NEXT_INSN (local_insn);
3204
 
3205
      /* Keep going while the next instruction is part of the same
3206
         VLIW packet (i.e., its a valid instruction and doesn't mark
3207
         the start of a new VLIW packet. */
3208
    }
3209
  while (local_insn &&
3210
         (GET_MODE (local_insn) != TImode) && (INSN_CODE (local_insn) != -1));
3211
 
3212
}
3213
 
3214
int
3215
picochip_sched_reorder (FILE * file, int verbose,
3216
                        rtx * ready ATTRIBUTE_UNUSED,
3217
                        int *n_readyp ATTRIBUTE_UNUSED, int clock)
3218
{
3219
 
3220
  if (verbose > 0)
3221
    fprintf (file, ";;\tClock %d\n", clock);
3222
 
3223
  return picochip_sched_issue_rate ();
3224
 
3225
}
3226
 
3227
int
3228
picochip_sched_lookahead (void)
3229
{
3230
  /* It should always be enough to lookahead by 2 insns. Only slot0/1 could
3231
     have a conflict. */
3232
  return 2;
3233
}
3234
 
3235
int
3236
picochip_sched_issue_rate (void)
3237
{
3238
  return 3;
3239
}
3240
 
3241
/* Adjust the scheduling cost between the two given instructions,
3242
   which have the given dependency. */
3243
int
3244
picochip_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
3245
{
3246
 
3247
  if (TARGET_DEBUG)
3248
    {
3249
      printf ("Sched Adjust Cost: %d->%d is %d\n",
3250
              INSN_UID (insn), INSN_UID (dep_insn), cost);
3251
 
3252
      printf ("  Dependency type:");
3253
      switch (REG_NOTE_KIND (link))
3254
        {
3255
        case 0:
3256
          printf ("Data\n");
3257
          break;
3258
        case REG_DEP_ANTI:
3259
          printf ("ANTI\n");
3260
          break;
3261
        case REG_DEP_OUTPUT:
3262
          printf ("OUTPUT\n");
3263
          break;
3264
        default:
3265
          printf ("Unknown (%d)\n", REG_NOTE_KIND (link));
3266
        }
3267
    }
3268
 
3269
  /* Anti-dependencies are used to enforce the ordering between a
3270
   * branch, and any subsequent instructions.  For example:
3271
   *
3272
   *   BNE someLabel
3273
   *   ADD.0 r0,r1,r2
3274
   *
3275
   * The ADD instruction must execute after the branch, and this is
3276
   * enforced using an anti-dependency.  Unfortunately, VLIW machines
3277
   * are happy to execute anti-dependent instructions in the same
3278
   * cycle, which then results in a schedule like the following being
3279
   * created:
3280
   *
3281
   *    BNE someLabel \ ADD.0 r0,r1,r2
3282
   *
3283
   * The instruction which would normally be conditionally executed
3284
   * depending upon the outcome of the branch, is now unconditionally
3285
   * executed every time.  To prevent this happening, any
3286
   * anti-dependencies between a branch and another instruction are
3287
   * promoted to become real dependencies.
3288
   */
3289
  if ((JUMP_P (dep_insn) || CALL_P(dep_insn)) && REG_NOTE_KIND (link) == REG_DEP_ANTI)
3290
    {
3291
 
3292
      if (TARGET_DEBUG)
3293
        printf ("Promoting anti-dependency %d->%d to a true-dependency\n",
3294
                INSN_UID (insn), INSN_UID (dep_insn));
3295
 
3296
      return 1;
3297
    }
3298
 
3299
  return cost;
3300
 
3301
}
3302
 
3303
/* Return the minimum of the two values */
3304
static int
3305
minimum (int a, int b)
3306
{
3307
  if (a < b)
3308
    return a;
3309
  if (b < a)
3310
    return b;
3311
  /* I dont expect to get to this function with a==b.*/
3312
  gcc_unreachable();
3313
}
3314
 
3315
 
3316
/* This function checks if the memory of the two stores are just off by 2 bytes.
3317
   It returns the lower memory operand's index.*/
3318
 
3319
static int
3320
memory_just_off (rtx opnd1, rtx opnd2)
3321
{
3322
  int offset1 = 0, offset2 = 0;
3323
  int reg1, reg2;
3324
 
3325
  if (GET_CODE(XEXP(opnd1, 0)) == PLUS && GET_CODE(XEXP(XEXP(opnd1, 0),1)) == CONST_INT)
3326
  {
3327
    offset1 = INTVAL(XEXP(XEXP(opnd1, 0), 1));
3328
    reg1 = REGNO(XEXP(XEXP(opnd1, 0), 0));
3329
  }
3330
  else
3331
  {
3332
    reg1 = REGNO(XEXP(opnd1, 0));
3333
  }
3334
  if (GET_CODE(XEXP(opnd2, 0)) == PLUS && GET_CODE(XEXP(XEXP(opnd2, 0), 1)) == CONST_INT)
3335
  {
3336
    offset2 = INTVAL(XEXP(XEXP(opnd2, 0), 1));
3337
    reg2 = REGNO(XEXP(XEXP(opnd2, 0), 0));
3338
  }
3339
  else
3340
  {
3341
    reg2 = REGNO(XEXP(opnd2, 0));
3342
  }
3343
 
3344
  /* Peepholing 2 STW/LDWs has the restriction that the resulting STL/LDL's address
3345
     should be 4 byte aligned. We can currently guarentee that only if the base
3346
     address is FP(R13) and the offset is aligned. */
3347
 
3348
  if (reg1 == reg2 && reg1 == 13 && abs(offset1-offset2) == 2 && minimum(offset1, offset2) % 4 == 0)
3349
    return (minimum(offset1, offset2) == offset1) ? 1:2;
3350
 
3351
  return 0;
3352
}
3353
 
3354
static int
3355
registers_just_off (rtx opnd1, rtx opnd2)
3356
{
3357
  int reg1, reg2;
3358
  reg1 = REGNO(opnd1);
3359
  reg2 = REGNO(opnd2);
3360
  if (abs(reg1-reg2) == 1 && minimum(reg1, reg2) % 2 == 0)
3361
    return (minimum(reg1, reg2) == reg1)?1:2;
3362
  return 0;
3363
}
3364
 
3365
/* Check to see if the two LDWs can be peepholed together into a LDL
3366
   They can be if the registers getting loaded into are contiguous
3367
   and the memory addresses are contiguous as well.
3368
   for eg.
3369
           LDW r2,[r11]x
3370
           LDW r3,[r11]x+1
3371
   can be merged together into
3372
           LDL r[3:2],[r11]
3373
 
3374
   NOTE:
3375
   1. The LDWs themselves only guarentee that r11 will be a 2-byte
3376
   aligned address. Only FP can be assumed to be 4 byte aligned.
3377
   2. The progression of addresses and the register numbers should
3378
   be similar. For eg., if you swap r2 and r3 in the above instructions,
3379
   the resultant pair cannot be merged.
3380
 
3381
*/
3382
bool
3383
ok_to_peephole_ldw(rtx opnd0, rtx opnd1, rtx opnd2, rtx opnd3)
3384
{
3385
  int memtest=0,regtest=0;
3386
  regtest = registers_just_off(opnd1,opnd3);
3387
  if (regtest == 0)
3388
    return false;
3389
 
3390
  memtest = memory_just_off(opnd0,opnd2);
3391
  if (memtest == 0)
3392
    return false;
3393
 
3394
  if (regtest == memtest)
3395
  {
3396
    return true;
3397
  }
3398
  return false;
3399
}
3400
 
3401
/* Similar to LDW peephole */
3402
bool
3403
ok_to_peephole_stw(rtx opnd0, rtx opnd1, rtx opnd2, rtx opnd3)
3404
{
3405
  int memtest=0,regtest=0;
3406
  regtest = registers_just_off(opnd1,opnd3);
3407
  if (regtest == 0)
3408
    return false;
3409
 
3410
  memtest = memory_just_off(opnd0,opnd2);
3411
  if (memtest == 0)
3412
    return false;
3413
 
3414
  if (regtest == memtest)
3415
  {
3416
    return true;
3417
  }
3418
  return false;
3419
}
3420
 
3421
 
3422
/* Generate a SImode register with the register number that is the smaller of the two */
3423
rtx
3424
gen_min_reg(rtx opnd1,rtx opnd2)
3425
{
3426
  return gen_rtx_REG (SImode, minimum(REGNO(opnd1),REGNO(opnd2)));
3427
}
3428
 
3429
/* Generate a SImode memory with the address that is the smaller of the two */
3430
rtx
3431
gen_SImode_mem(rtx opnd1,rtx opnd2)
3432
{
3433
  int offset1=0,offset2=0;
3434
  rtx reg;
3435
  if (GET_CODE(XEXP(opnd1,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd1,0),1)) == CONST_INT)
3436
  {
3437
    offset1 = INTVAL(XEXP(XEXP(opnd1,0),1));
3438
    reg = XEXP(XEXP(opnd1,0),0);
3439
  }
3440
  else
3441
  {
3442
    reg = XEXP(opnd1,0);
3443
  }
3444
  if (GET_CODE(XEXP(opnd2,0)) == PLUS && GET_CODE(XEXP(XEXP(opnd2,0),1)) == CONST_INT)
3445
  {
3446
    offset2 = INTVAL(XEXP(XEXP(opnd2,0),1));
3447
  }
3448
  rtx address = gen_rtx_PLUS (HImode, reg, GEN_INT(minimum(offset1,offset2)));
3449
  return gen_rtx_MEM(SImode,address);
3450
}
3451
 
3452
bool
3453
picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total)
3454
{
3455
 
3456
  int localTotal = 0;
3457
 
3458
  if (optimize_size)
3459
  {
3460
    /* Need to penalize immediates that need to be encoded as long constants.*/
3461
    if (code == CONST_INT && !(INTVAL (x) >= 0 && INTVAL (x) < 16))
3462
    {
3463
        *total = COSTS_N_INSNS(1);
3464
        return true;
3465
    }
3466
  }
3467
  switch (code)
3468
  {
3469
  case SYMBOL_REF:
3470
  case LABEL_REF:
3471
    *total = COSTS_N_INSNS (outer_code != MEM);
3472
    return true;
3473
    break;
3474
 
3475
  case IF_THEN_ELSE:
3476
    /* if_then_else come out of cbranch instructions. It will get split into
3477
       a condition code generating subtraction and a branch */
3478
    *total = COSTS_N_INSNS (2);
3479
    return true;
3480
    break;
3481
 
3482
  case AND:
3483
  case IOR:
3484
  case XOR:
3485
    if (GET_MODE(x) == SImode)
3486
      *total = COSTS_N_INSNS (2);
3487
    if (GET_MODE(x) == DImode)
3488
      *total = COSTS_N_INSNS (4);
3489
    return false;
3490
 
3491
  case MEM:
3492
    /* Byte Memory access on a NO_BYTE_ACCESS machine would be expensive */
3493
    if (GET_MODE(x) == QImode && !TARGET_HAS_BYTE_ACCESS)
3494
      *total = COSTS_N_INSNS (10);
3495
 
3496
    /* 64-bit accesses have to be done through 2 32-bit access */
3497
    if (GET_MODE(x) == DImode)
3498
      *total = COSTS_N_INSNS (2);
3499
    return false;
3500
    break;
3501
 
3502
  case ASHIFTRT:
3503
 
3504
    /* SImode shifts are expensive */
3505
    if (GET_MODE(x) == SImode)
3506
      *total = COSTS_N_INSNS (10);
3507
 
3508
    /* Register shift by constant is cheap. */
3509
    if ((GET_MODE(x) == QImode || GET_MODE(x) == HImode)
3510
        && GET_CODE(XEXP(x, 0)) == REG
3511
        && GET_CODE(XEXP(x, 1)) == CONST_INT)
3512
      *total = COSTS_N_INSNS (1);
3513
    else
3514
      *total = COSTS_N_INSNS (4);
3515
    return false;
3516
    break;
3517
 
3518
  case DIV:
3519
  case MOD:
3520
 
3521
    /* Divisions are more expensive than the default 7*/
3522
    if (GET_MODE(x) == SImode)
3523
      *total = COSTS_N_INSNS (20);
3524
    else
3525
      *total = COSTS_N_INSNS (12);
3526
    return false;
3527
    break;
3528
 
3529
  case MULT:
3530
    /* Look for the simple cases of multiplying register*register or
3531
       register*constant. */
3532
    if ((GET_MODE(x) == QImode || GET_MODE(x) == HImode)
3533
        && ((GET_CODE(XEXP(x, 0)) == REG
3534
           && (GET_CODE(XEXP(x, 1)) == REG || GET_CODE(XEXP(x,1)) == CONST_INT))
3535
           || (GET_CODE(XEXP(x, 0)) == ZERO_EXTEND
3536
               && GET_CODE(XEXP(XEXP(x, 0),0)) == REG
3537
               && GET_CODE(XEXP(x, 1)) == ZERO_EXTEND
3538
               && GET_CODE(XEXP(XEXP(x, 1),0)) == REG)))
3539
      {
3540
 
3541
        /* When optimising for size, multiplication by constant
3542
           should be discouraged slightly over multiplication by a
3543
           register. */
3544
        if (picochip_has_mac_unit)
3545
          {
3546
            /* Single cycle multiplication, but the result must be
3547
               loaded back into a general register afterwards. */
3548
            *total = COSTS_N_INSNS(2);
3549
            return true;
3550
          }
3551
        else if (picochip_has_mul_unit)
3552
          {
3553
            /* Single cycle multiplication. */
3554
            *total = COSTS_N_INSNS(1);
3555
            return true;
3556
          }
3557
        /* Else no multiply available. Use default cost. */
3558
 
3559
      }
3560
    break;
3561
 
3562
  default:
3563
    /* Do nothing. */
3564
    break;
3565
  }
3566
 
3567
  if (localTotal != 0)
3568
    {
3569
      *total = localTotal;
3570
      return true;
3571
    }
3572
  else
3573
    {
3574
      return false;
3575
    }
3576
 
3577
}
3578
 
3579
void
3580
picochip_final_prescan_insn (rtx insn, rtx * opvec ATTRIBUTE_UNUSED,
3581
                             int num_operands ATTRIBUTE_UNUSED)
3582
{
3583
  rtx local_insn;
3584
 
3585
  picochip_current_prescan_insn = insn;
3586
 
3587
  if (TARGET_DEBUG)
3588
    printf ("Final prescan on INSN %d with mode %s\n",
3589
            INSN_UID (insn), GET_MODE_NAME (GET_MODE (insn)));
3590
 
3591
  /* If this is the start of a new instruction cycle, or no scheduling
3592
     is used, then reset the VLIW status. */
3593
  if (GET_MODE (insn) == TImode || !picochip_schedule_type == DFA_TYPE_SPEED)
3594
    picochip_reset_vliw (insn);
3595
 
3596
  /* No VLIW scheduling occured, so don't go any further. */
3597
  if (picochip_schedule_type != DFA_TYPE_SPEED)
3598
    return;
3599
 
3600
  /* Look for the next printable instruction.  This loop terminates on
3601
     any recognisable instruction, and on any unrecognisable
3602
     instruction with TImode. */
3603
  local_insn = insn;
3604
  for (local_insn = NEXT_INSN (local_insn); local_insn;
3605
       local_insn = NEXT_INSN (local_insn))
3606
    {
3607
      if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn))
3608
        continue;
3609
      else if (!INSN_P (local_insn))
3610
        break;
3611
      else if (GET_MODE (local_insn) == TImode
3612
               || INSN_CODE (local_insn) != -1)
3613
        break;
3614
    }
3615
 
3616
  /* Set the continuation flag if the next instruction can be packed
3617
     with the current instruction (i.e., the next instruction is
3618
     valid, and isn't the start of a new cycle). */
3619
  picochip_vliw_continuation = (local_insn && NONDEBUG_INSN_P (local_insn) &&
3620
                                (GET_MODE (local_insn) != TImode));
3621
 
3622
}
3623
 
3624
/* Builtin functions. */
3625
/* Given a builtin function taking 2 operands (i.e., target + source),
3626
   emit the RTL for the underlying instruction. */
3627
static rtx
3628
picochip_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
3629
{
3630
  tree arg0;
3631
  rtx op0, pat;
3632
  enum machine_mode tmode, mode0;
3633
 
3634
  /* Grab the incoming argument and emit its RTL. */
3635
  arg0 = TREE_VALUE (arglist);
3636
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3637
 
3638
  /* Determine the modes of the instruction operands. */
3639
  tmode = insn_data[icode].operand[0].mode;
3640
  mode0 = insn_data[icode].operand[1].mode;
3641
 
3642
  /* Ensure that the incoming argument RTL is in a register of the
3643
     correct mode. */
3644
  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3645
    op0 = copy_to_mode_reg (mode0, op0);
3646
 
3647
  /* If there isn't a suitable target, emit a target register. */
3648
  if (target == 0
3649
      || GET_MODE (target) != tmode
3650
      || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3651
    target = gen_reg_rtx (tmode);
3652
 
3653
  /* Emit and return the new instruction. */
3654
  pat = GEN_FCN (icode) (target, op0);
3655
  if (!pat)
3656
    return 0;
3657
  emit_insn (pat);
3658
 
3659
  return target;
3660
 
3661
}
3662
 
3663
/* Given a builtin function taking 3 operands (i.e., target + two
3664
   source), emit the RTL for the underlying instruction. */
3665
static rtx
3666
picochip_expand_builtin_3op (enum insn_code icode, tree arglist, rtx target)
3667
{
3668
  tree arg0, arg1;
3669
  rtx op0, op1, pat;
3670
  enum machine_mode tmode, mode0, mode1;
3671
 
3672
  /* Grab the function's arguments. */
3673
  arg0 = TREE_VALUE (arglist);
3674
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3675
 
3676
  /* Emit rtl sequences for the function arguments. */
3677
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3678
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3679
 
3680
  /* Get the mode's of each of the instruction operands. */
3681
  tmode = insn_data[icode].operand[0].mode;
3682
  mode0 = insn_data[icode].operand[1].mode;
3683
  mode1 = insn_data[icode].operand[2].mode;
3684
 
3685
  /* Ensure that each of the function argument rtl sequences are in a
3686
     register of the correct mode. */
3687
  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3688
    op0 = copy_to_mode_reg (mode0, op0);
3689
  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3690
    op1 = copy_to_mode_reg (mode1, op1);
3691
 
3692
  /* If no target has been given, create a register to use as the target. */
3693
  if (target == 0
3694
      || GET_MODE (target) != tmode
3695
      || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3696
    target = gen_reg_rtx (tmode);
3697
 
3698
  /* Emit and return the new instruction. */
3699
  pat = GEN_FCN (icode) (target, op0, op1);
3700
  if (!pat)
3701
    return 0;
3702
  emit_insn (pat);
3703
 
3704
  return target;
3705
 
3706
}
3707
 
3708
/* Expand a builtin function which takes two arguments, and returns a void. */
3709
static rtx
3710
picochip_expand_builtin_2opvoid (enum insn_code icode, tree arglist)
3711
{
3712
  tree arg0, arg1;
3713
  rtx op0, op1, pat;
3714
  enum machine_mode mode0, mode1;
3715
 
3716
  /* Grab the function's arguments. */
3717
  arg0 = TREE_VALUE (arglist);
3718
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3719
 
3720
  /* Emit rtl sequences for the function arguments. */
3721
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3722
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3723
 
3724
  /* Get the mode's of each of the instruction operands. */
3725
  mode0 = insn_data[icode].operand[0].mode;
3726
  mode1 = insn_data[icode].operand[1].mode;
3727
 
3728
  /* Ensure that each of the function argument rtl sequences are in a
3729
     register of the correct mode. */
3730
  if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
3731
    op0 = copy_to_mode_reg (mode0, op0);
3732
  if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
3733
    op1 = copy_to_mode_reg (mode1, op1);
3734
 
3735
  /* Emit and return the new instruction. */
3736
  pat = GEN_FCN (icode) (op0, op1);
3737
  if (!pat)
3738
    return 0;
3739
  emit_insn (pat);
3740
 
3741
  return NULL_RTX;
3742
 
3743
}
3744
 
3745
/* Expand an array get into the corresponding RTL. */
3746
static rtx
3747
picochip_expand_array_get (tree arglist, rtx target)
3748
{
3749
  tree arg0, arg1, arg2;
3750
  rtx op0, op1, op2, pat;
3751
 
3752
  /* Grab the function's arguments. */
3753
  arg0 = TREE_VALUE (arglist);
3754
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3755
  arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3756
 
3757
  /* Emit rtl sequences for the function arguments. */
3758
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3759
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3760
  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
3761
 
3762
  /* The second and third operands must be constant.  Nothing else will
3763
     do. */
3764
  if (CONST_INT != GET_CODE (op1))
3765
    internal_error ("%s: Second source operand is not a constant",
3766
                    __FUNCTION__);
3767
  if (CONST_INT != GET_CODE (op2))
3768
    internal_error ("%s: Third source operand is not a constant",
3769
                    __FUNCTION__);
3770
 
3771
  /* If no target has been given, create a register to use as the target. */
3772
  if (target == 0 || GET_MODE (target) != SImode)
3773
    target = gen_reg_rtx (SImode);
3774
 
3775
  /* The first operand must be a HImode register or a constant.  If it
3776
     isn't, force it into a HImode register. */
3777
  if (GET_MODE (op0) != HImode || REG != GET_CODE (op0))
3778
    op0 = copy_to_mode_reg (HImode, op0);
3779
 
3780
 
3781
  /* Emit and return the new instruction. */
3782
  pat = gen_commsArrayGet (target, op0, op1, op2);
3783
  emit_insn (pat);
3784
 
3785
  return target;
3786
 
3787
}
3788
 
3789
/* Expand an array put into the corresponding RTL. */
3790
static rtx
3791
picochip_expand_array_put (tree arglist, rtx target)
3792
{
3793
  tree arg0, arg1, arg2, arg3;
3794
  rtx op0, op1, op2, op3, pat;
3795
 
3796
  /* Grab the function's arguments. */
3797
  arg0 = TREE_VALUE (arglist);
3798
  arg1 = TREE_VALUE (arglist->common.chain);
3799
  arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3800
  arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
3801
 
3802
  /* Emit rtl sequences for the function arguments. */
3803
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3804
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3805
  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
3806
  op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
3807
 
3808
  /* The first operand must be an SImode register. */
3809
  if (GET_MODE (op0) != SImode || REG != GET_CODE (op0))
3810
    op0 = copy_to_mode_reg (SImode, op0);
3811
 
3812
  /* The second (index) operand must be a HImode register, or a
3813
     constant.  If it isn't, force it into a HImode register. */
3814
  if (GET_MODE (op1) != HImode || REG != GET_CODE (op1))
3815
    op1 = copy_to_mode_reg (HImode, op1);
3816
 
3817
  /* The remaining operands must be constant.  Nothing else will do. */
3818
  if (CONST_INT != GET_CODE (op2))
3819
    internal_error ("%s: Third source operand is not a constant",
3820
                    __FUNCTION__);
3821
  if (CONST_INT != GET_CODE (op3))
3822
    internal_error ("%s: Fourth source operand is not a constant",
3823
                    __FUNCTION__);
3824
 
3825
  /* Emit and return the new instruction. */
3826
  pat = gen_commsArrayPut (op0, op1, op2, op3);
3827
  emit_insn (pat);
3828
 
3829
  return target;
3830
 
3831
}
3832
 
3833
/* Expand an array testport into the corresponding RTL. */
3834
static rtx
3835
picochip_expand_array_testport (tree arglist, rtx target)
3836
{
3837
  tree arg0, arg1, arg2;
3838
  rtx op0, op1, op2, pat;
3839
 
3840
  /* Grab the function's arguments. */
3841
  arg0 = TREE_VALUE (arglist);
3842
  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3843
  arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3844
 
3845
  /* Emit rtl sequences for the function arguments. */
3846
  op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3847
  op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
3848
  op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
3849
 
3850
  /* The first operand must be a HImode register, or a constant.  If it
3851
     isn't, force it into a HImode register. */
3852
  if (GET_MODE (op0) != HImode || REG != GET_CODE (op0))
3853
    op0 = copy_to_mode_reg (HImode, op0);
3854
 
3855
  /* The second and third operands must be constant.  Nothing else will
3856
     do. */
3857
  if (CONST_INT != GET_CODE (op1))
3858
    internal_error ("%s: Second source operand is not a constant",
3859
                    __FUNCTION__);
3860
  if (CONST_INT != GET_CODE (op2))
3861
    internal_error ("%s: Third source operand is not a constant",
3862
                    __FUNCTION__);
3863
 
3864
  /* If no target has been given, create a HImode register to use as
3865
     the target. */
3866
  if (target == 0 || GET_MODE (target) != HImode)
3867
    target = gen_reg_rtx (HImode);
3868
 
3869
  /* Emit and return the new instruction. */
3870
  pat = gen_commsArrayTestPort (target, op0, op1, op2);
3871
  emit_insn (pat);
3872
 
3873
  return target;
3874
 
3875
}
3876
 
3877
/* Generate a unique HALT instruction by giving the instruction a
3878
   unique integer. This integer makes no difference to the assembly
3879
   output (other than a comment indicating the supplied id), but the
3880
   presence of the unique integer prevents the compiler from combining
3881
   several different halt instructions into one instruction. This
3882
   means that each use of the halt instruction is unique, which in
3883
   turn means that assertions work as expected. */
3884
static rtx
3885
picochip_generate_halt (void)
3886
{
3887
  static int currentId = 0;
3888
  rtx id = GEN_INT (currentId);
3889
  currentId += 1;
3890
 
3891
  start_sequence();
3892
  emit_insn (gen_halt (id));
3893
 
3894
  /* A barrier is inserted to prevent the compiler from thinking that
3895
     it has to continue execution after the HALT.*/
3896
  emit_barrier ();
3897
 
3898
  rtx insns = get_insns();
3899
  end_sequence();
3900
  emit_insn (insns);
3901
 
3902
  return const0_rtx;
3903
}
3904
 
3905
/* Initialise the builtin functions.  Start by initialising
3906
   descriptions of different types of functions (e.g., void fn(int),
3907
   int fn(void)), and then use these to define the builtins. */
3908
void
3909
picochip_init_builtins (void)
3910
{
3911
  tree endlink = void_list_node;
3912
  tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
3913
  tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink);
3914
  tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink);
3915
  tree int_int_endlink =
3916
    tree_cons (NULL_TREE, integer_type_node, int_endlink);
3917
  tree int_int_int_endlink =
3918
    tree_cons (NULL_TREE, integer_type_node, int_int_endlink);
3919
  tree int_long_endlink =
3920
    tree_cons (NULL_TREE, integer_type_node, long_endlink);
3921
  tree pchar_type_node = build_pointer_type (char_type_node);
3922
  tree long_int_int_int_endlink =
3923
    tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink);
3924
 
3925
  tree int_ftype_void, int_ftype_int, int_ftype_int_int, void_ftype_pchar;
3926
  tree long_ftype_int, long_ftype_int_int, long_ftype_int_int_int;
3927
  tree void_ftype_int_long, int_ftype_int_int_int,
3928
    void_ftype_long_int_int_int;
3929
  tree void_ftype_void, void_ftype_int, unsigned_ftype_unsigned;
3930
 
3931
  /* void func (void) */
3932
  void_ftype_void = build_function_type (void_type_node, endlink);
3933
 
3934
  /* void func (void *) */
3935
  void_ftype_pchar
3936
    = build_function_type (void_type_node,
3937
                           tree_cons (NULL_TREE, pchar_type_node, endlink));
3938
 
3939
  /* int func (void) */
3940
  int_ftype_void = build_function_type (integer_type_node, endlink);
3941
 
3942
  /* void func (int) */
3943
  void_ftype_int = build_function_type (void_type_node, int_endlink);
3944
 
3945
  /* int func (int) */
3946
  int_ftype_int = build_function_type (integer_type_node, int_endlink);
3947
 
3948
  /* unsigned int func (unsigned int) */
3949
  unsigned_ftype_unsigned = build_function_type (unsigned_type_node, unsigned_endlink);
3950
 
3951
  /* int func(int, int) */
3952
  int_ftype_int_int
3953
    = build_function_type (integer_type_node, int_int_endlink);
3954
 
3955
  /* long func(int) */
3956
  long_ftype_int = build_function_type (long_integer_type_node, int_endlink);
3957
 
3958
  /* long func(int, int) */
3959
  long_ftype_int_int
3960
    = build_function_type (long_integer_type_node, int_int_endlink);
3961
 
3962
  /* long func(int, int, int) */
3963
  long_ftype_int_int_int
3964
    = build_function_type (long_integer_type_node, int_int_int_endlink);
3965
 
3966
  /* int func(int, int, int) */
3967
  int_ftype_int_int_int
3968
    = build_function_type (integer_type_node, int_int_int_endlink);
3969
 
3970
  /* void func(int, long) */
3971
  void_ftype_int_long
3972
    = build_function_type (void_type_node, int_long_endlink);
3973
 
3974
  /* void func(long, int, int, int) */
3975
  void_ftype_long_int_int_int
3976
    = build_function_type (void_type_node, long_int_int_int_endlink);
3977
 
3978
  /* Initialise the sign-bit-count function. */
3979
  add_builtin_function ("__builtin_sbc", int_ftype_int,
3980
                               PICOCHIP_BUILTIN_SBC, BUILT_IN_MD, NULL,
3981
                               NULL_TREE);
3982
  add_builtin_function ("picoSbc", int_ftype_int, PICOCHIP_BUILTIN_SBC,
3983
                               BUILT_IN_MD, NULL, NULL_TREE);
3984
 
3985
  /* Initialise the bit reverse function. */
3986
  add_builtin_function ("__builtin_brev", unsigned_ftype_unsigned,
3987
                               PICOCHIP_BUILTIN_BREV, BUILT_IN_MD, NULL,
3988
                               NULL_TREE);
3989
  add_builtin_function ("picoBrev", unsigned_ftype_unsigned,
3990
                               PICOCHIP_BUILTIN_BREV, BUILT_IN_MD, NULL,
3991
                               NULL_TREE);
3992
 
3993
  /* Initialise the byte swap function. */
3994
  add_builtin_function ("__builtin_byteswap", unsigned_ftype_unsigned,
3995
                               PICOCHIP_BUILTIN_BYTESWAP, BUILT_IN_MD, NULL,
3996
                               NULL_TREE);
3997
  add_builtin_function ("picoByteSwap", unsigned_ftype_unsigned,
3998
                               PICOCHIP_BUILTIN_BYTESWAP, BUILT_IN_MD, NULL,
3999
                               NULL_TREE);
4000
 
4001
  /* Initialise the ASRI function (note that while this can be coded
4002
     using a signed shift in C, extra scratch registers are required,
4003
     which we avoid by having a direct builtin to map to the
4004
     instruction). */
4005
  add_builtin_function ("__builtin_asri", int_ftype_int_int,
4006
                               PICOCHIP_BUILTIN_ASRI, BUILT_IN_MD, NULL,
4007
                               NULL_TREE);
4008
 
4009
  /* Initialise saturating addition. */
4010
  add_builtin_function ("__builtin_adds", int_ftype_int_int,
4011
                               PICOCHIP_BUILTIN_ADDS, BUILT_IN_MD, NULL,
4012
                               NULL_TREE);
4013
  add_builtin_function ("picoAdds", int_ftype_int_int,
4014
                               PICOCHIP_BUILTIN_ADDS, BUILT_IN_MD, NULL,
4015
                               NULL_TREE);
4016
 
4017
  /* Initialise saturating subtraction. */
4018
  add_builtin_function ("__builtin_subs", int_ftype_int_int,
4019
                               PICOCHIP_BUILTIN_SUBS, BUILT_IN_MD, NULL,
4020
                               NULL_TREE);
4021
  add_builtin_function ("picoSubs", int_ftype_int_int,
4022
                               PICOCHIP_BUILTIN_SUBS, BUILT_IN_MD, NULL,
4023
                               NULL_TREE);
4024
 
4025
  /* Scalar comms builtins. */
4026
  add_builtin_function ("__builtin_get", long_ftype_int,
4027
                               PICOCHIP_BUILTIN_GET, BUILT_IN_MD, NULL,
4028
                               NULL_TREE);
4029
  add_builtin_function ("__builtin_put", void_ftype_int_long,
4030
                               PICOCHIP_BUILTIN_PUT, BUILT_IN_MD, NULL,
4031
                               NULL_TREE);
4032
  add_builtin_function ("__builtin_testport", int_ftype_int,
4033
                               PICOCHIP_BUILTIN_TESTPORT, BUILT_IN_MD, NULL,
4034
                               NULL_TREE);
4035
 
4036
  /* Array comms builtins. */
4037
  add_builtin_function ("__builtin_put_array",
4038
                               void_ftype_long_int_int_int,
4039
                               PICOCHIP_BUILTIN_PUT_ARRAY, BUILT_IN_MD, NULL,
4040
                               NULL_TREE);
4041
  add_builtin_function ("__builtin_get_array", long_ftype_int_int_int,
4042
                               PICOCHIP_BUILTIN_GET_ARRAY, BUILT_IN_MD, NULL,
4043
                               NULL_TREE);
4044
  add_builtin_function ("__builtin_testport_array",
4045
                               int_ftype_int_int_int,
4046
                               PICOCHIP_BUILTIN_TESTPORT_ARRAY, BUILT_IN_MD,
4047
                               NULL, NULL_TREE);
4048
 
4049
  /* Halt instruction. Note that the builtin function is marked as
4050
     having the attribute `noreturn' so that the compiler realises
4051
     that the halt stops the program dead. */
4052
  tree noreturn = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4053
  add_builtin_function ("__builtin_halt", void_ftype_void,
4054
                               PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL,
4055
                               noreturn);
4056
  add_builtin_function ("picoHalt", void_ftype_void,
4057
                               PICOCHIP_BUILTIN_HALT, BUILT_IN_MD, NULL,
4058
                               noreturn);
4059
 
4060
}
4061
 
4062
/* Expand a call to a builtin function. */
4063
rtx
4064
picochip_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
4065
                         enum machine_mode mode ATTRIBUTE_UNUSED,
4066
                         int ignore ATTRIBUTE_UNUSED)
4067
{
4068
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
4069
  tree arglist = CALL_EXPR_ARGS(exp);
4070
  int fcode = DECL_FUNCTION_CODE (fndecl);
4071
 
4072
  switch (fcode)
4073
    {
4074
    case PICOCHIP_BUILTIN_ASRI:
4075
      return picochip_expand_builtin_3op (CODE_FOR_builtin_asri, arglist,
4076
                                          target);
4077
 
4078
    case PICOCHIP_BUILTIN_ADDS:
4079
      return picochip_expand_builtin_3op (CODE_FOR_sataddhi3, arglist,
4080
                                          target);
4081
 
4082
    case PICOCHIP_BUILTIN_SUBS:
4083
      return picochip_expand_builtin_3op (CODE_FOR_satsubhi3, arglist,
4084
                                          target);
4085
 
4086
    case PICOCHIP_BUILTIN_SBC:
4087
      return picochip_expand_builtin_2op (CODE_FOR_sbc, arglist, target);
4088
 
4089
    case PICOCHIP_BUILTIN_BREV:
4090
      return picochip_expand_builtin_2op (CODE_FOR_brev, arglist, target);
4091
 
4092
    case PICOCHIP_BUILTIN_BYTESWAP:
4093
      return picochip_expand_builtin_2op (CODE_FOR_bswaphi2, arglist, target);
4094
 
4095
    case PICOCHIP_BUILTIN_GET:
4096
      return picochip_expand_builtin_2op (CODE_FOR_commsGet, arglist, target);
4097
 
4098
    case PICOCHIP_BUILTIN_PUT:
4099
      return picochip_expand_builtin_2opvoid (CODE_FOR_commsPut, arglist);
4100
 
4101
    case PICOCHIP_BUILTIN_TESTPORT:
4102
      return picochip_expand_builtin_2op (CODE_FOR_commsTestPort, arglist,
4103
                                          target);
4104
 
4105
    case PICOCHIP_BUILTIN_PUT_ARRAY:
4106
      return picochip_expand_array_put (arglist, target);
4107
 
4108
    case PICOCHIP_BUILTIN_GET_ARRAY:
4109
      return picochip_expand_array_get (arglist, target);
4110
 
4111
    case PICOCHIP_BUILTIN_TESTPORT_ARRAY:
4112
      return picochip_expand_array_testport (arglist, target);
4113
 
4114
    case PICOCHIP_BUILTIN_HALT:
4115
      return picochip_generate_halt ();
4116
 
4117
    default:
4118
      gcc_unreachable();
4119
 
4120
    }
4121
 
4122
  /* Should really do something sensible here.  */
4123
  return NULL_RTX;
4124
}
4125
 
4126
/* Emit warnings. */
4127
static void
4128
picochip_warn_inefficient (const char *msg)
4129
{
4130
  if (TARGET_INEFFICIENT_WARNINGS)
4131
    warning (OPT_minefficient_warnings,
4132
             "%s (disable warning using -mno-inefficient-warnings)", msg);
4133
}
4134
 
4135
void
4136
warn_of_byte_access (void)
4137
{
4138
  static int warned = 0;
4139
 
4140
  if (!warned)
4141
    {
4142
      picochip_warn_inefficient
4143
        ("byte access is synthesised - consider using MUL AE");
4144
      warned = 1;
4145
    }
4146
 
4147
}
4148
 
4149
rtx
4150
picochip_function_value (const_tree valtype, const_tree func,
4151
                         bool outgoing ATTRIBUTE_UNUSED)
4152
{
4153
  enum machine_mode mode = TYPE_MODE (valtype);
4154
  int unsignedp = TYPE_UNSIGNED (valtype);
4155
 
4156
  /* Since we define PROMOTE_FUNCTION_RETURN, we must promote the mode
4157
     just as PROMOTE_MODE does.  */
4158
  mode = promote_function_mode (valtype, mode, &unsignedp, func, 1);
4159
 
4160
  return gen_rtx_REG (mode, 0);
4161
 
4162
}
4163
 
4164
/* Check that the value of the given mode will fit in the register of
4165
   the given mode. */
4166
int
4167
picochip_hard_regno_mode_ok (int regno, enum machine_mode mode)
4168
{
4169
 
4170
  if (GET_MODE_CLASS (mode) == MODE_CC)
4171
    return regno == CC_REGNUM;
4172
 
4173
  /* If the CC register is being used, then only CC mode values are
4174
     allowed (which have already been tested). */
4175
  if (regno == CC_REGNUM || regno == ACC_REGNUM)
4176
    return 0;
4177
 
4178
  /* Must be a valid register. */
4179
  if (regno > 16)
4180
    return 0;
4181
 
4182
  /* Modes QI and HI may be placed in any register except the CC. */
4183
  if (mode == QImode || mode == HImode)
4184
    return 1;
4185
 
4186
  /* DI must be in a quad register. */
4187
  if (mode == DImode)
4188
    return (regno % 4 == 0);
4189
 
4190
  /* All other modes must be placed in a even numbered register. */
4191
  return !(regno & 1);
4192
 
4193
}
4194
 
4195
/* Extract the lower and upper components of a constant value. */
4196
 
4197
rtx
4198
picochip_get_low_const (rtx value)
4199
{
4200
  return gen_int_mode (INTVAL (value) & 0xFFFF, HImode);
4201
}
4202
 
4203
rtx
4204
picochip_get_high_const (rtx value)
4205
{
4206
  /*return GEN_INT ((((INTVAL (value) >> 16) & 0xFFFF) ^ 0x8000) - 0x8000); */
4207
  return gen_int_mode ((INTVAL (value) >> 16) & 0xFFFF, HImode);
4208
}
4209
 
4210
 
4211
/* Loading and storing QImode values to and from memory in a machine
4212
   without byte access requires might require a scratch
4213
   register.  However, the scratch register might correspond to the
4214
   register in which the value is being loaded.  To ensure that a
4215
   scratch register is supplied which is definitely different to the
4216
   output register, request a register pair.  This effectively gives a
4217
   choice of two registers to choose from, so that we a guaranteed to
4218
   get at least one register which is different to the output
4219
   register.  This trick is taken from the alpha implementation. */
4220
enum reg_class
4221
picochip_secondary_reload (bool in_p,
4222
                                 rtx x ATTRIBUTE_UNUSED,
4223
                                 enum reg_class cla ATTRIBUTE_UNUSED,
4224
                                 enum machine_mode mode,
4225
                                 secondary_reload_info *sri)
4226
{
4227
  if (mode == QImode && !TARGET_HAS_BYTE_ACCESS)
4228
  {
4229
    if (in_p == 0)
4230
      sri->icode = CODE_FOR_reload_outqi;
4231
    else
4232
      sri->icode = CODE_FOR_reload_inqi;
4233
  }
4234
 
4235
  /* We dont need to return a register class type when we need only a
4236
     scratch register. It realizes the scratch register type by looking
4237
     at the instruction definition for sri->icode. We only need to
4238
     return the register type when we need intermediaries for copies.*/
4239
  return NO_REGS;
4240
}
4241
 
4242
/* Return true if the given memory operand can be aligned to a
4243
   word+offset memory reference (e.g., FP+3 can be converted into the
4244
   memory operand FP+2, with the offset 1). */
4245
int
4246
picochip_alignable_memory_operand (rtx mem_operand,
4247
                                   enum machine_mode mode ATTRIBUTE_UNUSED)
4248
{
4249
  rtx address;
4250
 
4251
  /* Not a mem operand. Refuse immediately. */
4252
  if (MEM != GET_CODE (mem_operand))
4253
    return 0;
4254
 
4255
  address = XEXP (mem_operand, 0);
4256
 
4257
  /* Return true if a PLUS of the SP and a (valid) constant, or SP itself. */
4258
  return ((PLUS == GET_CODE (address) &&
4259
           REGNO (XEXP (address, 0)) == STACK_POINTER_REGNUM &&
4260
           CONST_INT == GET_CODE (XEXP (address, 1)) &&
4261
           picochip_const_ok_for_letter_p (INTVAL (XEXP (address, 1)), 'K'))
4262
          || (REG == GET_CODE (address)
4263
              && REGNO (address) == STACK_POINTER_REGNUM));
4264
 
4265
}
4266
 
4267
/* Return true if the given memory reference is to a word aligned
4268
   address.  Currently this means it must be either SP, or
4269
   SP+offset.  We could replace this function with alignable
4270
   memory references in the above function?. */
4271
int
4272
picochip_word_aligned_memory_reference (rtx operand)
4273
{
4274
 
4275
 
4276
  /* The address must be the SP register, or a constant, aligned
4277
     offset from SP which doesn't exceed the FP+offset
4278
     restrictions. */
4279
  return ((PLUS == GET_CODE (operand)
4280
           && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
4281
           && picochip_is_aligned (INTVAL (XEXP (operand, 1)), 16)
4282
           && picochip_const_ok_for_letter_p (INTVAL (XEXP (operand, 1)),
4283
                                                'K'))
4284
          || (REG == GET_CODE (operand)
4285
              && REGNO (operand) == STACK_POINTER_REGNUM));
4286
 
4287
}
4288
 
4289
/* Given an alignable memory location, convert the memory location
4290
   into a HI mode access, storing the new memory reference in
4291
   paligned_mem, and the number of bits by which to shift in pbitnum
4292
   (i.e., given a reference to FP+3, this creates an aligned reference
4293
   of FP+2, with an 8-bit shift). This code is a modification of that
4294
   found in the Alpha port. */
4295
void
4296
picochip_get_hi_aligned_mem (rtx ref, rtx * paligned_mem, rtx * pbitnum)
4297
{
4298
  rtx base;
4299
  HOST_WIDE_INT offset = 0;
4300
 
4301
  gcc_assert (GET_CODE (ref) == MEM);
4302
 
4303
  if (reload_in_progress && !memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
4304
    {
4305
      base = find_replacement (&XEXP (ref, 0));
4306
 
4307
      gcc_assert(memory_address_p (GET_MODE (ref), base));
4308
    }
4309
  else
4310
    {
4311
      base = XEXP (ref, 0);
4312
    }
4313
 
4314
  if (GET_CODE (base) == PLUS)
4315
    {
4316
      offset += INTVAL (XEXP (base, 1));
4317
      base = XEXP (base, 0);
4318
    }
4319
 
4320
  *paligned_mem = widen_memory_access (ref, HImode, (offset & ~1) - offset);
4321
 
4322
  if (offset > 0)
4323
    {
4324
      if (TARGET_DEBUG)
4325
        {
4326
          printf
4327
            ("Found non-zero offset in get_hi_aligned_mem - check that the correct value is being used (as this functionality hasn't been exploited yet).\n");
4328
        }
4329
    }
4330
 
4331
  *pbitnum = GEN_INT ((offset & 1) * 8);
4332
 
4333
}
4334
 
4335
/* Return true if the given operand is an absolute address in memory
4336
   (i.e., a symbolic offset). */
4337
int
4338
picochip_absolute_memory_operand (rtx op,
4339
                                  enum machine_mode mode ATTRIBUTE_UNUSED)
4340
{
4341
 
4342
  if (MEM == GET_CODE (op))
4343
    {
4344
      rtx address = XEXP (op, 0);
4345
 
4346
      /* Symbols are valid absolute addresses. */
4347
      if (SYMBOL_REF == GET_CODE (address))
4348
        return 1;
4349
 
4350
      /* Constant offsets to symbols are valid absolute addresses. */
4351
      if (CONST == GET_CODE (address) &&
4352
          PLUS == GET_CODE (XEXP (address, 0)) &&
4353
          SYMBOL_REF == GET_CODE (XEXP (XEXP (address, 0), 0)) &&
4354
          CONST_INT == GET_CODE (XEXP (XEXP (address, 0), 1)))
4355
        return 1;
4356
 
4357
    }
4358
  else
4359
    return 0;
4360
 
4361
  /* Symbols are valid absolute addresses. */
4362
  if (SYMBOL_REF == GET_CODE (XEXP (op, 0)))
4363
    return 1;
4364
 
4365
 
4366
  return 0;
4367
 
4368
}
4369
 
4370
void
4371
picochip_asm_named_section (const char *name,
4372
                            unsigned int flags ATTRIBUTE_UNUSED,
4373
                            tree decl ATTRIBUTE_UNUSED)
4374
{
4375
  fprintf (asm_out_file, ".section %s\n", name);
4376
}
4377
 
4378
 
4379
/* Check if we can make a conditional copy instruction.  This is emitted as an
4380
   instruction to set the condition register, followed by an instruction which
4381
   uses the condition registers to perform the conditional move. */
4382
int
4383
picochip_check_conditional_copy (rtx * operands)
4384
{
4385
 
4386
  rtx branch_op_0 = XEXP (operands[1], 0);
4387
  rtx branch_op_1 = XEXP (operands[1], 1);
4388
 
4389
  /* Only HI mode conditional moves are currently allowed.  Can we add
4390
     SI mode moves? */
4391
  if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
4392
    return 0;
4393
 
4394
  /* Is the comparison valid? Only allow operands which are registers
4395
     if they are HImode.  SI mode comparisons against 0 could be
4396
     handled using logical operations (e.g., SIreg != 0 when low ||
4397
     high). Need to find test cases to provoke this though (fixunssfdi
4398
     in libgcc does, but is complicated). */
4399
  if (GET_MODE (branch_op_0) != HImode ||
4400
       !(register_operand (branch_op_0, GET_MODE (branch_op_0))))
4401
    return 0;
4402
  if (GET_MODE (branch_op_1) != HImode ||
4403
       !(picochip_comparison_operand (branch_op_1, GET_MODE (branch_op_1))))
4404
    return 0;
4405
 
4406
  return 1;
4407
 
4408
}
4409
 
4410
 
4411
static rtx
4412
picochip_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
4413
{
4414
  rtx addr;
4415
  if (incoming_p)
4416
    addr = arg_pointer_rtx;
4417
  else
4418
    addr = plus_constant (stack_pointer_rtx, -2 * UNITS_PER_WORD);
4419
  return gen_frame_mem (Pmode, addr);
4420
}

powered by: WebSVN 2.1.0

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