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