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