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