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