gcc * config/rl78/rl78.c (rl78_force_nonfar_3): Remove optimization
[official-gcc.git] / gcc / config / rl78 / rl78.c
blobe74d6c38a3187773c39ba5ab2bdf672da56f5143
1 /* Subroutines used for code generation on Renesas RL78 processors.
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "cfghooks.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "df.h"
29 #include "alias.h"
30 #include "fold-const.h"
31 #include "varasm.h"
32 #include "stor-layout.h"
33 #include "calls.h"
34 #include "regs.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "output.h"
38 #include "insn-attr.h"
39 #include "flags.h"
40 #include "expmed.h"
41 #include "dojump.h"
42 #include "explow.h"
43 #include "emit-rtl.h"
44 #include "stmt.h"
45 #include "expr.h"
46 #include "insn-codes.h"
47 #include "optabs.h"
48 #include "libfuncs.h"
49 #include "recog.h"
50 #include "diagnostic-core.h"
51 #include "toplev.h"
52 #include "reload.h"
53 #include "cfgrtl.h"
54 #include "cfganal.h"
55 #include "lcm.h"
56 #include "cfgbuild.h"
57 #include "cfgcleanup.h"
58 #include "tm_p.h"
59 #include "debug.h"
60 #include "target.h"
61 #include "langhooks.h"
62 #include "rl78-protos.h"
63 #include "dumpfile.h"
64 #include "tree-pass.h"
65 #include "context.h"
66 #include "tm-constrs.h" /* for satisfies_constraint_*(). */
67 #include "insn-flags.h" /* for gen_*(). */
68 #include "builtins.h"
69 #include "stringpool.h"
71 /* This file should be included last. */
72 #include "target-def.h"
74 static inline bool is_interrupt_func (const_tree decl);
75 static inline bool is_brk_interrupt_func (const_tree decl);
76 static void rl78_reorg (void);
77 static const char *rl78_strip_name_encoding (const char *);
78 static const char *rl78_strip_nonasm_name_encoding (const char *);
79 static section * rl78_select_section (tree, int, unsigned HOST_WIDE_INT);
82 /* Debugging statements are tagged with DEBUG0 only so that they can
83 be easily enabled individually, by replacing the '0' with '1' as
84 needed. */
85 #define DEBUG0 0
86 #define DEBUG1 1
88 /* REGISTER_NAMES has the names for individual 8-bit registers, but
89 these have the names we need to use when referring to 16-bit
90 register pairs. */
91 static const char * const word_regnames[] =
93 "ax", "AX", "bc", "BC", "de", "DE", "hl", "HL",
94 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
95 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
96 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
97 "sp", "ap", "psw", "es", "cs"
100 struct GTY(()) machine_function
102 /* If set, the rest of the fields have been computed. */
103 int computed;
104 /* Which register pairs need to be pushed in the prologue. */
105 int need_to_push [FIRST_PSEUDO_REGISTER / 2];
107 /* These fields describe the frame layout... */
108 /* arg pointer */
109 /* 4 bytes for saved PC */
110 int framesize_regs;
111 /* frame pointer */
112 int framesize_locals;
113 int framesize_outgoing;
114 /* stack pointer */
115 int framesize;
117 /* If set, recog is allowed to match against the "real" patterns. */
118 int real_insns_ok;
119 /* If set, recog is allowed to match against the "virtual" patterns. */
120 int virt_insns_ok;
121 /* Set if the current function needs to clean up any trampolines. */
122 int trampolines_used;
123 /* True if the ES register is used and hence
124 needs to be saved inside interrupt handlers. */
125 bool uses_es;
128 /* This is our init_machine_status, as set in
129 rl78_option_override. */
130 static struct machine_function *
131 rl78_init_machine_status (void)
133 struct machine_function *m;
135 m = ggc_cleared_alloc<machine_function> ();
136 m->virt_insns_ok = 1;
138 return m;
141 /* This pass converts virtual instructions using virtual registers, to
142 real instructions using real registers. Rather than run it as
143 reorg, we reschedule it before vartrack to help with debugging. */
144 namespace
146 const pass_data pass_data_rl78_devirt =
148 RTL_PASS, /* type */
149 "devirt", /* name */
150 OPTGROUP_NONE, /* optinfo_flags */
151 TV_MACH_DEP, /* tv_id */
152 0, /* properties_required */
153 0, /* properties_provided */
154 0, /* properties_destroyed */
155 0, /* todo_flags_start */
156 0, /* todo_flags_finish */
159 class pass_rl78_devirt : public rtl_opt_pass
161 public:
162 pass_rl78_devirt (gcc::context *ctxt)
163 : rtl_opt_pass (pass_data_rl78_devirt, ctxt)
167 /* opt_pass methods: */
168 virtual unsigned int execute (function *)
170 rl78_reorg ();
171 return 0;
174 } // anon namespace
176 rtl_opt_pass *
177 make_pass_rl78_devirt (gcc::context *ctxt)
179 return new pass_rl78_devirt (ctxt);
182 /* Redundant move elimination pass. Must be run after the basic block
183 reordering pass for the best effect. */
185 static unsigned int
186 move_elim_pass (void)
188 rtx_insn *insn, *ninsn;
189 rtx prev = NULL_RTX;
191 for (insn = get_insns (); insn; insn = ninsn)
193 rtx set;
195 ninsn = next_nonnote_nondebug_insn (insn);
197 if ((set = single_set (insn)) == NULL_RTX)
199 prev = NULL_RTX;
200 continue;
203 /* If we have two SET insns in a row (without anything
204 between them) and the source of the second one is the
205 destination of the first one, and vice versa, then we
206 can eliminate the second SET. */
207 if (prev
208 && rtx_equal_p (SET_DEST (prev), SET_SRC (set))
209 && rtx_equal_p (SET_DEST (set), SET_SRC (prev))
210 /* ... and none of the operands are volatile. */
211 && ! volatile_refs_p (SET_SRC (prev))
212 && ! volatile_refs_p (SET_DEST (prev))
213 && ! volatile_refs_p (SET_SRC (set))
214 && ! volatile_refs_p (SET_DEST (set)))
216 if (dump_file)
217 fprintf (dump_file, " Delete insn %d because it is redundant\n",
218 INSN_UID (insn));
220 delete_insn (insn);
221 prev = NULL_RTX;
223 else
224 prev = set;
227 if (dump_file)
228 print_rtl_with_bb (dump_file, get_insns (), 0);
230 return 0;
233 namespace
235 const pass_data pass_data_rl78_move_elim =
237 RTL_PASS, /* type */
238 "move_elim", /* name */
239 OPTGROUP_NONE, /* optinfo_flags */
240 TV_MACH_DEP, /* tv_id */
241 0, /* properties_required */
242 0, /* properties_provided */
243 0, /* properties_destroyed */
244 0, /* todo_flags_start */
245 0, /* todo_flags_finish */
248 class pass_rl78_move_elim : public rtl_opt_pass
250 public:
251 pass_rl78_move_elim (gcc::context *ctxt)
252 : rtl_opt_pass (pass_data_rl78_move_elim, ctxt)
256 /* opt_pass methods: */
257 virtual unsigned int execute (function *) { return move_elim_pass (); }
259 } // anon namespace
261 rtl_opt_pass *
262 make_pass_rl78_move_elim (gcc::context *ctxt)
264 return new pass_rl78_move_elim (ctxt);
267 #undef TARGET_ASM_FILE_START
268 #define TARGET_ASM_FILE_START rl78_asm_file_start
270 static void
271 rl78_asm_file_start (void)
273 int i;
275 if (TARGET_G10)
277 /* The memory used is 0xffec8 to 0xffedf; real registers are in
278 0xffee0 to 0xffee7. */
279 for (i = 8; i < 32; i++)
280 fprintf (asm_out_file, "r%d\t=\t0x%x\n", i, 0xffec0 + i);
282 else
284 for (i = 0; i < 8; i++)
286 fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i);
287 fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i);
288 fprintf (asm_out_file, "r%d\t=\t0x%x\n", 24 + i, 0xffee0 + i);
292 opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g);
293 struct register_pass_info rl78_devirt_info =
295 rl78_devirt_pass,
296 "pro_and_epilogue",
298 PASS_POS_INSERT_BEFORE
301 opt_pass *rl78_move_elim_pass = make_pass_rl78_move_elim (g);
302 struct register_pass_info rl78_move_elim_info =
304 rl78_move_elim_pass,
305 "bbro",
307 PASS_POS_INSERT_AFTER
310 register_pass (& rl78_devirt_info);
311 register_pass (& rl78_move_elim_info);
314 void
315 rl78_output_symbol_ref (FILE * file, rtx sym)
317 tree type = SYMBOL_REF_DECL (sym);
318 const char *str = XSTR (sym, 0);
320 if (str[0] == '*')
322 fputs (str + 1, file);
324 else
326 str = rl78_strip_nonasm_name_encoding (str);
327 if (type && TREE_CODE (type) == FUNCTION_DECL)
329 fprintf (file, "%%code(");
330 assemble_name (file, str);
331 fprintf (file, ")");
333 else
334 assemble_name (file, str);
338 #undef TARGET_OPTION_OVERRIDE
339 #define TARGET_OPTION_OVERRIDE rl78_option_override
341 static void
342 rl78_option_override (void)
344 flag_omit_frame_pointer = 1;
345 flag_no_function_cse = 1;
346 flag_split_wide_types = 0;
348 init_machine_status = rl78_init_machine_status;
350 if (TARGET_ALLREGS)
352 int i;
354 for (i = 24; i < 32; i++)
355 fixed_regs[i] = 0;
358 if (TARGET_ES0
359 && strcmp (lang_hooks.name, "GNU C")
360 && strcmp (lang_hooks.name, "GNU C11")
361 && strcmp (lang_hooks.name, "GNU C89")
362 && strcmp (lang_hooks.name, "GNU C99")
363 /* Compiling with -flto results in a language of GNU GIMPLE being used... */
364 && strcmp (lang_hooks.name, "GNU GIMPLE"))
365 /* Address spaces are currently only supported by C. */
366 error ("-mes0 can only be used with C");
368 switch (rl78_cpu_type)
370 case CPU_UNINIT:
371 rl78_cpu_type = CPU_G14;
372 if (rl78_mul_type == MUL_UNINIT)
373 rl78_mul_type = MUL_NONE;
374 break;
376 case CPU_G10:
377 switch (rl78_mul_type)
379 case MUL_UNINIT: rl78_mul_type = MUL_NONE; break;
380 case MUL_NONE: break;
381 case MUL_G13: error ("-mmul=g13 cannot be used with -mcpu=g10"); break;
382 case MUL_G14: error ("-mmul=g14 cannot be used with -mcpu=g10"); break;
384 break;
386 case CPU_G13:
387 switch (rl78_mul_type)
389 case MUL_UNINIT: rl78_mul_type = MUL_G13; break;
390 case MUL_NONE: break;
391 case MUL_G13: break;
392 /* The S2 core does not have mul/div instructions. */
393 case MUL_G14: error ("-mmul=g14 cannot be used with -mcpu=g13"); break;
395 break;
397 case CPU_G14:
398 switch (rl78_mul_type)
400 case MUL_UNINIT: rl78_mul_type = MUL_G14; break;
401 case MUL_NONE: break;
402 case MUL_G14: break;
403 /* The G14 core does not have the hardware multiply peripheral used by the
404 G13 core, hence you cannot use G13 multipliy routines on G14 hardware. */
405 case MUL_G13: error ("-mmul=g13 cannot be used with -mcpu=g14"); break;
407 break;
411 /* Most registers are 8 bits. Some are 16 bits because, for example,
412 gcc doesn't like dealing with $FP as a register pair (the second
413 half of $fp is also 2 to keep reload happy wrt register pairs, but
414 no register class includes it). This table maps register numbers
415 to size in bytes. */
416 static const int register_sizes[] =
418 1, 1, 1, 1, 1, 1, 1, 1,
419 1, 1, 1, 1, 1, 1, 1, 1,
420 1, 1, 1, 1, 1, 1, 2, 2,
421 1, 1, 1, 1, 1, 1, 1, 1,
422 2, 2, 1, 1, 1
425 /* Predicates used in the MD patterns. This one is true when virtual
426 insns may be matched, which typically means before (or during) the
427 devirt pass. */
428 bool
429 rl78_virt_insns_ok (void)
431 if (cfun)
432 return cfun->machine->virt_insns_ok;
433 return true;
436 /* Predicates used in the MD patterns. This one is true when real
437 insns may be matched, which typically means after (or during) the
438 devirt pass. */
439 bool
440 rl78_real_insns_ok (void)
442 if (cfun)
443 return cfun->machine->real_insns_ok;
444 return false;
447 /* Implements HARD_REGNO_NREGS. */
449 rl78_hard_regno_nregs (int regno, machine_mode mode)
451 int rs = register_sizes[regno];
452 if (rs < 1)
453 rs = 1;
454 return ((GET_MODE_SIZE (mode) + rs - 1) / rs);
457 /* Implements HARD_REGNO_MODE_OK. */
459 rl78_hard_regno_mode_ok (int regno, machine_mode mode)
461 int s = GET_MODE_SIZE (mode);
463 if (s < 1)
464 return 0;
465 /* These are not to be used by gcc. */
466 if (regno == 23 || regno == ES_REG || regno == CS_REG)
467 return 0;
468 /* $fp can always be accessed as a 16-bit value. */
469 if (regno == FP_REG && s == 2)
470 return 1;
471 if (regno < SP_REG)
473 /* Since a reg-reg move is really a reg-mem move, we must
474 enforce alignment. */
475 if (s > 1 && (regno % 2))
476 return 0;
477 return 1;
479 if (s == CC_REGNUM)
480 return (mode == BImode);
481 /* All other registers must be accessed in their natural sizes. */
482 if (s == register_sizes [regno])
483 return 1;
484 return 0;
487 /* Simplify_gen_subreg() doesn't handle memory references the way we
488 need it to below, so we use this function for when we must get a
489 valid subreg in a "natural" state. */
490 static rtx
491 rl78_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
493 if (GET_CODE (r) == MEM)
494 return adjust_address (r, mode, byte);
495 else
496 return simplify_gen_subreg (mode, r, omode, byte);
499 /* Used by movsi. Split SImode moves into two HImode moves, using
500 appropriate patterns for the upper and lower halves of symbols. */
501 void
502 rl78_expand_movsi (rtx *operands)
504 rtx op00, op02, op10, op12;
506 op00 = rl78_subreg (HImode, operands[0], SImode, 0);
507 op02 = rl78_subreg (HImode, operands[0], SImode, 2);
508 if (GET_CODE (operands[1]) == CONST
509 || GET_CODE (operands[1]) == SYMBOL_REF)
511 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
512 op10 = gen_rtx_CONST (HImode, op10);
513 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
514 op12 = gen_rtx_CONST (HImode, op12);
516 else
518 op10 = rl78_subreg (HImode, operands[1], SImode, 0);
519 op12 = rl78_subreg (HImode, operands[1], SImode, 2);
522 if (rtx_equal_p (operands[0], operands[1]))
524 else if (rtx_equal_p (op00, op12))
526 emit_move_insn (op02, op12);
527 emit_move_insn (op00, op10);
529 else
531 emit_move_insn (op00, op10);
532 emit_move_insn (op02, op12);
536 /* Generate code to move an SImode value. */
537 void
538 rl78_split_movsi (rtx *operands, enum machine_mode omode)
540 rtx op00, op02, op10, op12;
542 op00 = rl78_subreg (HImode, operands[0], omode, 0);
543 op02 = rl78_subreg (HImode, operands[0], omode, 2);
545 if (GET_CODE (operands[1]) == CONST
546 || GET_CODE (operands[1]) == SYMBOL_REF)
548 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
549 op10 = gen_rtx_CONST (HImode, op10);
550 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
551 op12 = gen_rtx_CONST (HImode, op12);
553 else
555 op10 = rl78_subreg (HImode, operands[1], omode, 0);
556 op12 = rl78_subreg (HImode, operands[1], omode, 2);
559 if (rtx_equal_p (operands[0], operands[1]))
561 else if (rtx_equal_p (op00, op12))
563 operands[2] = op02;
564 operands[4] = op12;
565 operands[3] = op00;
566 operands[5] = op10;
568 else
570 operands[2] = op00;
571 operands[4] = op10;
572 operands[3] = op02;
573 operands[5] = op12;
577 /* Used by various two-operand expanders which cannot accept all
578 operands in the "far" namespace. Force some such operands into
579 registers so that each pattern has at most one far operand. */
581 rl78_force_nonfar_2 (rtx *operands, rtx (*gen)(rtx,rtx))
583 int did = 0;
584 rtx temp_reg = NULL;
586 /* FIXME: in the future, be smarter about only doing this if the
587 other operand is also far, assuming the devirtualizer can also
588 handle that. */
589 if (rl78_far_p (operands[0]))
591 temp_reg = operands[0];
592 operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
593 did = 1;
595 if (!did)
596 return 0;
598 emit_insn (gen (operands[0], operands[1]));
599 if (temp_reg)
600 emit_move_insn (temp_reg, operands[0]);
601 return 1;
604 /* Likewise, but for three-operand expanders. */
606 rl78_force_nonfar_3 (rtx *operands, rtx (*gen)(rtx,rtx,rtx))
608 int did = 0;
609 rtx temp_reg = NULL;
611 /* FIXME: Likewise. */
612 if (rl78_far_p (operands[1]))
614 rtx temp_reg = gen_reg_rtx (GET_MODE (operands[1]));
615 emit_move_insn (temp_reg, operands[1]);
616 operands[1] = temp_reg;
617 did = 1;
619 if (rl78_far_p (operands[0]))
621 temp_reg = operands[0];
622 operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
623 did = 1;
625 if (!did)
626 return 0;
628 emit_insn (gen (operands[0], operands[1], operands[2]));
629 if (temp_reg)
630 emit_move_insn (temp_reg, operands[0]);
631 return 1;
634 #undef TARGET_CAN_ELIMINATE
635 #define TARGET_CAN_ELIMINATE rl78_can_eliminate
637 static bool
638 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUSED)
640 return true;
643 /* Returns true if the given register needs to be saved by the
644 current function. */
645 static bool
646 need_to_save (unsigned int regno)
648 if (is_interrupt_func (cfun->decl))
650 /* We don't know what devirt will need */
651 if (regno < 8)
652 return true;
654 /* We don't need to save registers that have
655 been reserved for interrupt handlers. */
656 if (regno > 23)
657 return false;
659 /* If the handler is a non-leaf function then it may call
660 non-interrupt aware routines which will happily clobber
661 any call_used registers, so we have to preserve them.
662 We do not have to worry about the frame pointer register
663 though, as that is handled below. */
664 if (!crtl->is_leaf && call_used_regs[regno] && regno < 22)
665 return true;
667 /* Otherwise we only have to save a register, call_used
668 or not, if it is used by this handler. */
669 return df_regs_ever_live_p (regno);
672 if (regno == FRAME_POINTER_REGNUM
673 && (frame_pointer_needed || df_regs_ever_live_p (regno)))
674 return true;
675 if (fixed_regs[regno])
676 return false;
677 if (crtl->calls_eh_return)
678 return true;
679 if (df_regs_ever_live_p (regno)
680 && !call_used_regs[regno])
681 return true;
682 return false;
685 /* We use this to wrap all emitted insns in the prologue. */
686 static rtx
687 F (rtx x)
689 RTX_FRAME_RELATED_P (x) = 1;
690 return x;
693 /* Compute all the frame-related fields in our machine_function
694 structure. */
695 static void
696 rl78_compute_frame_info (void)
698 int i;
700 cfun->machine->computed = 1;
701 cfun->machine->framesize_regs = 0;
702 cfun->machine->framesize_locals = get_frame_size ();
703 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
705 for (i = 0; i < 16; i ++)
706 if (need_to_save (i * 2) || need_to_save (i * 2 + 1))
708 cfun->machine->need_to_push [i] = 1;
709 cfun->machine->framesize_regs += 2;
711 else
712 cfun->machine->need_to_push [i] = 0;
714 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
715 cfun->machine->framesize_locals ++;
717 cfun->machine->framesize = (cfun->machine->framesize_regs
718 + cfun->machine->framesize_locals
719 + cfun->machine->framesize_outgoing);
722 /* Returns true if the provided function has the specified attribute. */
723 static inline bool
724 has_func_attr (const_tree decl, const char * func_attr)
726 if (decl == NULL_TREE)
727 decl = current_function_decl;
729 return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
732 /* Returns true if the provided function has the "interrupt" attribute. */
733 static inline bool
734 is_interrupt_func (const_tree decl)
736 return has_func_attr (decl, "interrupt") || has_func_attr (decl, "brk_interrupt");
739 /* Returns true if the provided function has the "brk_interrupt" attribute. */
740 static inline bool
741 is_brk_interrupt_func (const_tree decl)
743 return has_func_attr (decl, "brk_interrupt");
746 /* Check "interrupt" attributes. */
747 static tree
748 rl78_handle_func_attribute (tree * node,
749 tree name,
750 tree args,
751 int flags ATTRIBUTE_UNUSED,
752 bool * no_add_attrs)
754 gcc_assert (DECL_P (* node));
755 gcc_assert (args == NULL_TREE);
757 if (TREE_CODE (* node) != FUNCTION_DECL)
759 warning (OPT_Wattributes, "%qE attribute only applies to functions",
760 name);
761 * no_add_attrs = true;
764 /* FIXME: We ought to check that the interrupt and exception
765 handler attributes have been applied to void functions. */
766 return NULL_TREE;
769 /* Check "naked" attributes. */
770 static tree
771 rl78_handle_naked_attribute (tree * node,
772 tree name ATTRIBUTE_UNUSED,
773 tree args,
774 int flags ATTRIBUTE_UNUSED,
775 bool * no_add_attrs)
777 gcc_assert (DECL_P (* node));
778 gcc_assert (args == NULL_TREE);
780 if (TREE_CODE (* node) != FUNCTION_DECL)
782 warning (OPT_Wattributes, "naked attribute only applies to functions");
783 * no_add_attrs = true;
786 /* Disable warnings about this function - eg reaching the end without
787 seeing a return statement - because the programmer is doing things
788 that gcc does not know about. */
789 TREE_NO_WARNING (* node) = 1;
791 return NULL_TREE;
794 /* Check "saddr" attributes. */
795 static tree
796 rl78_handle_saddr_attribute (tree * node,
797 tree name,
798 tree args ATTRIBUTE_UNUSED,
799 int flags ATTRIBUTE_UNUSED,
800 bool * no_add_attrs)
802 gcc_assert (DECL_P (* node));
804 if (TREE_CODE (* node) == FUNCTION_DECL)
806 warning (OPT_Wattributes, "%qE attribute doesn't apply to functions",
807 name);
808 * no_add_attrs = true;
811 return NULL_TREE;
814 #undef TARGET_ATTRIBUTE_TABLE
815 #define TARGET_ATTRIBUTE_TABLE rl78_attribute_table
817 /* Table of RL78-specific attributes. */
818 const struct attribute_spec rl78_attribute_table[] =
820 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
821 affects_type_identity. */
822 { "interrupt", 0, 0, true, false, false, rl78_handle_func_attribute,
823 false },
824 { "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute,
825 false },
826 { "naked", 0, 0, true, false, false, rl78_handle_naked_attribute,
827 false },
828 { "saddr", 0, 0, true, false, false, rl78_handle_saddr_attribute,
829 false },
830 { NULL, 0, 0, false, false, false, NULL, false }
835 /* Break down an address RTX into its component base/index/addend
836 portions and return TRUE if the address is of a valid form, else
837 FALSE. */
838 static bool
839 characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
841 *base = NULL_RTX;
842 *index = NULL_RTX;
843 *addend = NULL_RTX;
845 if (GET_CODE (x) == UNSPEC
846 && XINT (x, 1) == UNS_ES_ADDR)
847 x = XVECEXP (x, 0, 1);
849 if (GET_CODE (x) == REG)
851 *base = x;
852 return true;
855 /* We sometimes get these without the CONST wrapper */
856 if (GET_CODE (x) == PLUS
857 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
858 && GET_CODE (XEXP (x, 1)) == CONST_INT)
860 *addend = x;
861 return true;
864 if (GET_CODE (x) == PLUS)
866 *base = XEXP (x, 0);
867 x = XEXP (x, 1);
869 if (GET_CODE (*base) == SUBREG)
871 if (GET_MODE (*base) == HImode
872 && GET_MODE (XEXP (*base, 0)) == SImode
873 && GET_CODE (XEXP (*base, 0)) == REG)
875 /* This is a throw-away rtx just to tell everyone
876 else what effective register we're using. */
877 *base = gen_rtx_REG (HImode, REGNO (XEXP (*base, 0)));
881 if (GET_CODE (*base) != REG
882 && GET_CODE (x) == REG)
884 rtx tmp = *base;
885 *base = x;
886 x = tmp;
889 if (GET_CODE (*base) != REG)
890 return false;
892 if (GET_CODE (x) == ZERO_EXTEND
893 && GET_CODE (XEXP (x, 0)) == REG)
895 *index = XEXP (x, 0);
896 return false;
900 switch (GET_CODE (x))
902 case PLUS:
903 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
904 && GET_CODE (XEXP (x, 0)) == CONST_INT)
906 *addend = x;
907 return true;
909 /* fall through */
910 case MEM:
911 case REG:
912 return false;
914 case SUBREG:
915 switch (GET_CODE (XEXP (x, 0)))
917 case CONST:
918 case SYMBOL_REF:
919 case CONST_INT:
920 *addend = x;
921 return true;
922 default:
923 return false;
926 case CONST:
927 case SYMBOL_REF:
928 case CONST_INT:
929 *addend = x;
930 return true;
932 default:
933 return false;
936 return false;
939 /* Used by the Whb constraint. Match addresses that use HL+B or HL+C
940 addressing. */
941 bool
942 rl78_hl_b_c_addr_p (rtx op)
944 rtx hl, bc;
946 if (GET_CODE (op) != PLUS)
947 return false;
948 hl = XEXP (op, 0);
949 bc = XEXP (op, 1);
950 if (GET_CODE (hl) == ZERO_EXTEND)
952 rtx tmp = hl;
953 hl = bc;
954 bc = tmp;
956 if (GET_CODE (hl) != REG)
957 return false;
958 if (GET_CODE (bc) != ZERO_EXTEND)
959 return false;
960 bc = XEXP (bc, 0);
961 if (GET_CODE (bc) != REG)
962 return false;
963 if (REGNO (hl) != HL_REG)
964 return false;
965 if (REGNO (bc) != B_REG && REGNO (bc) != C_REG)
966 return false;
968 return true;
971 #define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
973 /* Return the appropriate mode for a named address address. */
975 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
976 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
978 static enum machine_mode
979 rl78_addr_space_address_mode (addr_space_t addrspace)
981 switch (addrspace)
983 case ADDR_SPACE_GENERIC:
984 return HImode;
985 case ADDR_SPACE_NEAR:
986 return HImode;
987 case ADDR_SPACE_FAR:
988 return SImode;
989 default:
990 gcc_unreachable ();
994 /* Used in various constraints and predicates to match operands in the
995 "far" address space. */
997 rl78_far_p (rtx x)
999 if (! MEM_P (x))
1000 return 0;
1001 #if DEBUG0
1002 fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
1003 fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
1004 #endif
1006 /* Not all far addresses are legitimate, because the devirtualizer
1007 can't handle them. */
1008 if (! rl78_as_legitimate_address (GET_MODE (x), XEXP (x, 0), false, ADDR_SPACE_FAR))
1009 return 0;
1011 return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) == 32;
1014 /* Return the appropriate mode for a named address pointer. */
1015 #undef TARGET_ADDR_SPACE_POINTER_MODE
1016 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
1018 static machine_mode
1019 rl78_addr_space_pointer_mode (addr_space_t addrspace)
1021 switch (addrspace)
1023 case ADDR_SPACE_GENERIC:
1024 return HImode;
1025 case ADDR_SPACE_NEAR:
1026 return HImode;
1027 case ADDR_SPACE_FAR:
1028 return SImode;
1029 default:
1030 gcc_unreachable ();
1034 /* Returns TRUE for valid addresses. */
1035 #undef TARGET_VALID_POINTER_MODE
1036 #define TARGET_VALID_POINTER_MODE rl78_valid_pointer_mode
1038 static bool
1039 rl78_valid_pointer_mode (machine_mode m)
1041 return (m == HImode || m == SImode);
1044 #undef TARGET_LEGITIMATE_CONSTANT_P
1045 #define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant
1047 static bool
1048 rl78_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED)
1050 return true;
1053 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
1054 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P rl78_as_legitimate_address
1056 bool
1057 rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
1058 bool strict ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED)
1060 rtx base, index, addend;
1061 bool is_far_addr = false;
1062 int as_bits;
1064 as_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (as));
1066 if (GET_CODE (x) == UNSPEC
1067 && XINT (x, 1) == UNS_ES_ADDR)
1069 x = XVECEXP (x, 0, 1);
1070 is_far_addr = true;
1073 if (as_bits == 16 && is_far_addr)
1074 return false;
1076 if (! characterize_address (x, &base, &index, &addend))
1077 return false;
1079 /* We can't extract the high/low portions of a PLUS address
1080 involving a register during devirtualization, so make sure all
1081 such __far addresses do not have addends. This forces GCC to do
1082 the sum separately. */
1083 if (addend && base && as_bits == 32 && GET_MODE (base) == SImode)
1084 return false;
1086 if (base && index)
1088 int ir = REGNO (index);
1089 int br = REGNO (base);
1091 #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
1092 OK (REG_IS (br, HL_REG) && REG_IS (ir, B_REG), "[hl+b]");
1093 OK (REG_IS (br, HL_REG) && REG_IS (ir, C_REG), "[hl+c]");
1094 return false;
1097 if (strict && base && GET_CODE (base) == REG && REGNO (base) >= FIRST_PSEUDO_REGISTER)
1098 return false;
1100 if (! cfun->machine->virt_insns_ok && base && GET_CODE (base) == REG
1101 && REGNO (base) >= 8 && REGNO (base) <= 31)
1102 return false;
1104 return true;
1107 /* Determine if one named address space is a subset of another. */
1108 #undef TARGET_ADDR_SPACE_SUBSET_P
1109 #define TARGET_ADDR_SPACE_SUBSET_P rl78_addr_space_subset_p
1111 static bool
1112 rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
1114 int subset_bits;
1115 int superset_bits;
1117 subset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (subset));
1118 superset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (superset));
1120 return (subset_bits <= superset_bits);
1123 #undef TARGET_ADDR_SPACE_CONVERT
1124 #define TARGET_ADDR_SPACE_CONVERT rl78_addr_space_convert
1126 /* Convert from one address space to another. */
1127 static rtx
1128 rl78_addr_space_convert (rtx op, tree from_type, tree to_type)
1130 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
1131 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
1132 rtx result;
1133 int to_bits;
1134 int from_bits;
1136 to_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (to_as));
1137 from_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (from_as));
1139 if (to_bits < from_bits)
1141 rtx tmp;
1142 /* This is unpredictable, as we're truncating off usable address
1143 bits. */
1145 warning (OPT_Waddress, "converting far pointer to near pointer");
1146 result = gen_reg_rtx (HImode);
1147 if (GET_CODE (op) == SYMBOL_REF
1148 || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER))
1149 tmp = gen_rtx_raw_SUBREG (HImode, op, 0);
1150 else
1151 tmp = simplify_subreg (HImode, op, SImode, 0);
1152 gcc_assert (tmp != NULL_RTX);
1153 emit_move_insn (result, tmp);
1154 return result;
1156 else if (to_bits > from_bits)
1158 /* This always works. */
1159 result = gen_reg_rtx (SImode);
1160 emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op);
1161 if (TREE_CODE (from_type) == POINTER_TYPE
1162 && TREE_CODE (TREE_TYPE (from_type)) == FUNCTION_TYPE)
1163 emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx);
1164 else
1165 emit_move_insn (rl78_subreg (HImode, result, SImode, 2), GEN_INT (0x0f));
1166 return result;
1168 else
1169 return op;
1170 gcc_unreachable ();
1173 /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */
1174 bool
1175 rl78_regno_mode_code_ok_for_base_p (int regno, machine_mode mode ATTRIBUTE_UNUSED,
1176 addr_space_t address_space ATTRIBUTE_UNUSED,
1177 int outer_code ATTRIBUTE_UNUSED, int index_code)
1179 if (regno <= SP_REG && regno >= 16)
1180 return true;
1181 if (index_code == REG)
1182 return (regno == HL_REG);
1183 if (regno == C_REG || regno == B_REG || regno == E_REG || regno == L_REG)
1184 return true;
1185 return false;
1188 /* Implements MODE_CODE_BASE_REG_CLASS. */
1189 enum reg_class
1190 rl78_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
1191 addr_space_t address_space ATTRIBUTE_UNUSED,
1192 int outer_code ATTRIBUTE_UNUSED,
1193 int index_code ATTRIBUTE_UNUSED)
1195 return V_REGS;
1198 /* Typical stack layout should looks like this after the function's prologue:
1201 -- ^
1202 | | \ |
1203 | | arguments saved | Increasing
1204 | | on the stack | addresses
1205 PARENT arg pointer -> | | /
1206 -------------------------- ---- -------------------
1207 CHILD |ret | return address
1209 | | \
1210 | | call saved
1211 | | registers
1212 frame pointer -> | | /
1214 | | \
1215 | | local
1216 | | variables
1217 | | /
1219 | | \
1220 | | outgoing | Decreasing
1221 | | arguments | addresses
1222 current stack pointer -> | | / |
1223 -------------------------- ---- ------------------ V
1224 | | */
1226 /* Implements INITIAL_ELIMINATION_OFFSET. The frame layout is
1227 described in the machine_Function struct definition, above. */
1229 rl78_initial_elimination_offset (int from, int to)
1231 int rv = 0; /* as if arg to arg */
1233 rl78_compute_frame_info ();
1235 switch (to)
1237 case STACK_POINTER_REGNUM:
1238 rv += cfun->machine->framesize_outgoing;
1239 rv += cfun->machine->framesize_locals;
1240 /* Fall through. */
1241 case FRAME_POINTER_REGNUM:
1242 rv += cfun->machine->framesize_regs;
1243 rv += 4;
1244 break;
1245 default:
1246 gcc_unreachable ();
1249 switch (from)
1251 case FRAME_POINTER_REGNUM:
1252 rv -= 4;
1253 rv -= cfun->machine->framesize_regs;
1254 case ARG_POINTER_REGNUM:
1255 break;
1256 default:
1257 gcc_unreachable ();
1260 return rv;
1263 static int
1264 rl78_is_naked_func (void)
1266 return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE);
1269 /* Expand the function prologue (from the prologue pattern). */
1270 void
1271 rl78_expand_prologue (void)
1273 int i, fs;
1274 rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
1275 rtx ax = gen_rtx_REG (HImode, AX_REG);
1276 int rb = 0;
1278 if (rl78_is_naked_func ())
1279 return;
1281 /* Always re-compute the frame info - the register usage may have changed. */
1282 rl78_compute_frame_info ();
1284 if (flag_stack_usage_info)
1285 current_function_static_stack_size = cfun->machine->framesize;
1287 if (is_interrupt_func (cfun->decl) && !TARGET_G10)
1288 for (i = 0; i < 4; i++)
1289 if (cfun->machine->need_to_push [i])
1291 /* Select Bank 0 if we are using any registers from Bank 0. */
1292 emit_insn (gen_sel_rb (GEN_INT (0)));
1293 break;
1296 for (i = 0; i < 16; i++)
1297 if (cfun->machine->need_to_push [i])
1299 int reg = i * 2;
1301 if (TARGET_G10)
1303 if (reg >= 8)
1305 emit_move_insn (ax, gen_rtx_REG (HImode, reg));
1306 reg = AX_REG;
1309 else
1311 int need_bank = i/4;
1313 if (need_bank != rb)
1315 emit_insn (gen_sel_rb (GEN_INT (need_bank)));
1316 rb = need_bank;
1320 F (emit_insn (gen_push (gen_rtx_REG (HImode, reg))));
1323 if (rb != 0)
1324 emit_insn (gen_sel_rb (GEN_INT (0)));
1326 /* Save ES register inside interrupt functions if it is used. */
1327 if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
1329 emit_insn (gen_movqi_from_es (gen_rtx_REG (QImode, A_REG)));
1330 F (emit_insn (gen_push (ax)));
1333 if (frame_pointer_needed)
1335 F (emit_move_insn (ax, sp));
1336 F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), ax));
1339 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1340 if (fs > 0)
1342 /* If we need to subtract more than 254*3 then it is faster and
1343 smaller to move SP into AX and perform the subtraction there. */
1344 if (fs > 254 * 3)
1346 rtx insn;
1348 emit_move_insn (ax, sp);
1349 emit_insn (gen_subhi3 (ax, ax, GEN_INT (fs)));
1350 insn = F (emit_move_insn (sp, ax));
1351 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1352 gen_rtx_SET (sp, gen_rtx_PLUS (HImode, sp,
1353 GEN_INT (-fs))));
1355 else
1357 while (fs > 0)
1359 int fs_byte = (fs > 254) ? 254 : fs;
1361 F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte))));
1362 fs -= fs_byte;
1368 /* Expand the function epilogue (from the epilogue pattern). */
1369 void
1370 rl78_expand_epilogue (void)
1372 int i, fs;
1373 rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
1374 rtx ax = gen_rtx_REG (HImode, AX_REG);
1375 int rb = 0;
1377 if (rl78_is_naked_func ())
1378 return;
1380 if (frame_pointer_needed)
1382 emit_move_insn (ax, gen_rtx_REG (HImode, FRAME_POINTER_REGNUM));
1383 emit_move_insn (sp, ax);
1385 else
1387 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1388 if (fs > 254 * 3)
1390 emit_move_insn (ax, sp);
1391 emit_insn (gen_addhi3 (ax, ax, GEN_INT (fs)));
1392 emit_move_insn (sp, ax);
1394 else
1396 while (fs > 0)
1398 int fs_byte = (fs > 254) ? 254 : fs;
1400 emit_insn (gen_addhi3 (sp, sp, GEN_INT (fs_byte)));
1401 fs -= fs_byte;
1406 if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
1408 emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
1409 emit_insn (gen_movqi_to_es (gen_rtx_REG (QImode, A_REG)));
1412 for (i = 15; i >= 0; i--)
1413 if (cfun->machine->need_to_push [i])
1415 rtx dest = gen_rtx_REG (HImode, i * 2);
1417 if (TARGET_G10)
1419 if (i < 8)
1420 emit_insn (gen_pop (dest));
1421 else
1423 emit_insn (gen_pop (ax));
1424 emit_move_insn (dest, ax);
1425 /* Generate a USE of the pop'd register so that DCE will not eliminate the move. */
1426 emit_insn (gen_use (dest));
1429 else
1431 int need_bank = i / 4;
1433 if (need_bank != rb)
1435 emit_insn (gen_sel_rb (GEN_INT (need_bank)));
1436 rb = need_bank;
1438 emit_insn (gen_pop (dest));
1442 if (rb != 0)
1443 emit_insn (gen_sel_rb (GEN_INT (0)));
1445 if (cfun->machine->trampolines_used)
1446 emit_insn (gen_trampoline_uninit ());
1448 if (is_brk_interrupt_func (cfun->decl))
1449 emit_jump_insn (gen_brk_interrupt_return ());
1450 else if (is_interrupt_func (cfun->decl))
1451 emit_jump_insn (gen_interrupt_return ());
1452 else
1453 emit_jump_insn (gen_rl78_return ());
1456 /* Likewise, for exception handlers. */
1457 void
1458 rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED)
1460 /* FIXME - replace this with an indirect jump with stack adjust. */
1461 emit_jump_insn (gen_rl78_return ());
1464 #undef TARGET_ASM_FUNCTION_PROLOGUE
1465 #define TARGET_ASM_FUNCTION_PROLOGUE rl78_start_function
1467 /* We don't use this to actually emit the function prologue. We use
1468 this to insert a comment in the asm file describing the
1469 function. */
1470 static void
1471 rl78_start_function (FILE *file, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
1473 int i;
1475 if (cfun->machine->framesize == 0)
1476 return;
1477 fprintf (file, "\t; start of function\n");
1479 if (cfun->machine->framesize_regs)
1481 fprintf (file, "\t; push %d:", cfun->machine->framesize_regs);
1482 for (i = 0; i < 16; i ++)
1483 if (cfun->machine->need_to_push[i])
1484 fprintf (file, " %s", word_regnames[i*2]);
1485 fprintf (file, "\n");
1488 if (frame_pointer_needed)
1489 fprintf (file, "\t; $fp points here (r22)\n");
1491 if (cfun->machine->framesize_locals)
1492 fprintf (file, "\t; locals: %d byte%s\n", cfun->machine->framesize_locals,
1493 cfun->machine->framesize_locals == 1 ? "" : "s");
1495 if (cfun->machine->framesize_outgoing)
1496 fprintf (file, "\t; outgoing: %d byte%s\n", cfun->machine->framesize_outgoing,
1497 cfun->machine->framesize_outgoing == 1 ? "" : "s");
1499 if (cfun->machine->uses_es)
1500 fprintf (file, "\t; uses ES register\n");
1503 /* Return an RTL describing where a function return value of type RET_TYPE
1504 is held. */
1506 #undef TARGET_FUNCTION_VALUE
1507 #define TARGET_FUNCTION_VALUE rl78_function_value
1509 static rtx
1510 rl78_function_value (const_tree ret_type,
1511 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1512 bool outgoing ATTRIBUTE_UNUSED)
1514 machine_mode mode = TYPE_MODE (ret_type);
1516 return gen_rtx_REG (mode, 8);
1519 #undef TARGET_PROMOTE_FUNCTION_MODE
1520 #define TARGET_PROMOTE_FUNCTION_MODE rl78_promote_function_mode
1522 static machine_mode
1523 rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
1524 machine_mode mode,
1525 int *punsignedp ATTRIBUTE_UNUSED,
1526 const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED)
1528 return mode;
1531 /* Return an RTL expression describing the register holding a function
1532 parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
1533 be passed on the stack. CUM describes the previous parameters to the
1534 function and NAMED is false if the parameter is part of a variable
1535 parameter list, or the last named parameter before the start of a
1536 variable parameter list. */
1538 #undef TARGET_FUNCTION_ARG
1539 #define TARGET_FUNCTION_ARG rl78_function_arg
1541 static rtx
1542 rl78_function_arg (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
1543 machine_mode mode ATTRIBUTE_UNUSED,
1544 const_tree type ATTRIBUTE_UNUSED,
1545 bool named ATTRIBUTE_UNUSED)
1547 return NULL_RTX;
1550 #undef TARGET_FUNCTION_ARG_ADVANCE
1551 #define TARGET_FUNCTION_ARG_ADVANCE rl78_function_arg_advance
1553 static void
1554 rl78_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, const_tree type,
1555 bool named ATTRIBUTE_UNUSED)
1557 int rounded_size;
1558 CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
1560 rounded_size = ((mode == BLKmode)
1561 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
1562 if (rounded_size & 1)
1563 rounded_size ++;
1564 (*cum) += rounded_size;
1567 #undef TARGET_FUNCTION_ARG_BOUNDARY
1568 #define TARGET_FUNCTION_ARG_BOUNDARY rl78_function_arg_boundary
1570 static unsigned int
1571 rl78_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
1572 const_tree type ATTRIBUTE_UNUSED)
1574 return 16;
1577 /* Supported modifier letters:
1579 A - address of a MEM
1580 S - SADDR form of a real register
1581 v - real register corresponding to a virtual register
1582 m - minus - negative of CONST_INT value.
1583 C - inverse of a conditional (NE vs EQ for example)
1584 C - complement of an integer
1585 z - collapsed conditional
1586 s - shift count mod 8
1587 S - shift count mod 16
1588 r - reverse shift count (8-(count mod 8))
1589 B - bit position
1591 h - bottom HI of an SI
1592 H - top HI of an SI
1593 q - bottom QI of an HI
1594 Q - top QI of an HI
1595 e - third QI of an SI (i.e. where the ES register gets values from)
1596 E - fourth QI of an SI (i.e. MSB)
1598 p - Add +0 to a zero-indexed HL based address.
1601 /* Implements the bulk of rl78_print_operand, below. We do it this
1602 way because we need to test for a constant at the top level and
1603 insert the '#', but not test for it anywhere else as we recurse
1604 down into the operand. */
1605 static void
1606 rl78_print_operand_1 (FILE * file, rtx op, int letter)
1608 int need_paren;
1610 switch (GET_CODE (op))
1612 case MEM:
1613 if (letter == 'A')
1614 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1615 else
1617 if (rl78_far_p (op))
1619 fprintf (file, "es:");
1620 if (GET_CODE (XEXP (op, 0)) == UNSPEC)
1621 op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1));
1623 if (letter == 'H')
1625 op = adjust_address (op, HImode, 2);
1626 letter = 0;
1628 if (letter == 'h')
1630 op = adjust_address (op, HImode, 0);
1631 letter = 0;
1633 if (letter == 'Q')
1635 op = adjust_address (op, QImode, 1);
1636 letter = 0;
1638 if (letter == 'q')
1640 op = adjust_address (op, QImode, 0);
1641 letter = 0;
1643 if (letter == 'e')
1645 op = adjust_address (op, QImode, 2);
1646 letter = 0;
1648 if (letter == 'E')
1650 op = adjust_address (op, QImode, 3);
1651 letter = 0;
1653 if (CONSTANT_P (XEXP (op, 0)))
1655 if (!rl78_saddr_p (op))
1656 fprintf (file, "!");
1657 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1659 else if (GET_CODE (XEXP (op, 0)) == PLUS
1660 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF)
1662 if (!rl78_saddr_p (op))
1663 fprintf (file, "!");
1664 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1666 else if (GET_CODE (XEXP (op, 0)) == PLUS
1667 && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
1668 && REGNO (XEXP (XEXP (op, 0), 0)) == 2)
1670 rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u');
1671 fprintf (file, "[");
1672 rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0);
1673 if (letter == 'p' && GET_CODE (XEXP (op, 0)) == REG)
1674 fprintf (file, "+0");
1675 fprintf (file, "]");
1677 else
1679 op = XEXP (op, 0);
1680 fprintf (file, "[");
1681 rl78_print_operand_1 (file, op, letter);
1682 if (letter == 'p' && REG_P (op) && REGNO (op) == 6)
1683 fprintf (file, "+0");
1684 fprintf (file, "]");
1687 break;
1689 case REG:
1690 if (letter == 'Q')
1691 fprintf (file, "%s", reg_names [REGNO (op) | 1]);
1692 else if (letter == 'H')
1693 fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1694 else if (letter == 'q')
1695 fprintf (file, "%s", reg_names [REGNO (op) & ~1]);
1696 else if (letter == 'e')
1697 fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1698 else if (letter == 'E')
1699 fprintf (file, "%s", reg_names [REGNO (op) + 3]);
1700 else if (letter == 'S')
1701 fprintf (file, "0x%x", 0xffef8 + REGNO (op));
1702 else if (GET_MODE (op) == HImode
1703 && ! (REGNO (op) & ~0xfe))
1705 if (letter == 'v')
1706 fprintf (file, "%s", word_regnames [REGNO (op) % 8]);
1707 else
1708 fprintf (file, "%s", word_regnames [REGNO (op)]);
1710 else
1711 fprintf (file, "%s", reg_names [REGNO (op)]);
1712 break;
1714 case CONST_INT:
1715 if (letter == 'Q')
1716 fprintf (file, "%ld", INTVAL (op) >> 8);
1717 else if (letter == 'H')
1718 fprintf (file, "%ld", INTVAL (op) >> 16);
1719 else if (letter == 'q')
1720 fprintf (file, "%ld", INTVAL (op) & 0xff);
1721 else if (letter == 'h')
1722 fprintf (file, "%ld", INTVAL (op) & 0xffff);
1723 else if (letter == 'e')
1724 fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
1725 else if (letter == 'B')
1727 int ival = INTVAL (op);
1728 if (ival == -128)
1729 ival = 0x80;
1730 if (exact_log2 (ival) >= 0)
1731 fprintf (file, "%d", exact_log2 (ival));
1732 else
1733 fprintf (file, "%d", exact_log2 (~ival & 0xff));
1735 else if (letter == 'E')
1736 fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff);
1737 else if (letter == 'm')
1738 fprintf (file, "%ld", - INTVAL (op));
1739 else if (letter == 's')
1740 fprintf (file, "%ld", INTVAL (op) % 8);
1741 else if (letter == 'S')
1742 fprintf (file, "%ld", INTVAL (op) % 16);
1743 else if (letter == 'r')
1744 fprintf (file, "%ld", 8 - (INTVAL (op) % 8));
1745 else if (letter == 'C')
1746 fprintf (file, "%ld", (INTVAL (op) ^ 0x8000) & 0xffff);
1747 else
1748 fprintf (file, "%ld", INTVAL (op));
1749 break;
1751 case CONST:
1752 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1753 break;
1755 case ZERO_EXTRACT:
1757 int bits = INTVAL (XEXP (op, 1));
1758 int ofs = INTVAL (XEXP (op, 2));
1759 if (bits == 16 && ofs == 0)
1760 fprintf (file, "%%lo16(");
1761 else if (bits == 16 && ofs == 16)
1762 fprintf (file, "%%hi16(");
1763 else if (bits == 8 && ofs == 16)
1764 fprintf (file, "%%hi8(");
1765 else
1766 gcc_unreachable ();
1767 rl78_print_operand_1 (file, XEXP (op, 0), 0);
1768 fprintf (file, ")");
1770 break;
1772 case ZERO_EXTEND:
1773 if (GET_CODE (XEXP (op, 0)) == REG)
1774 fprintf (file, "%s", reg_names [REGNO (XEXP (op, 0))]);
1775 else
1776 print_rtl (file, op);
1777 break;
1779 case PLUS:
1780 need_paren = 0;
1781 if (letter == 'H')
1783 fprintf (file, "%%hi16(");
1784 need_paren = 1;
1785 letter = 0;
1787 if (letter == 'h')
1789 fprintf (file, "%%lo16(");
1790 need_paren = 1;
1791 letter = 0;
1793 if (letter == 'e')
1795 fprintf (file, "%%hi8(");
1796 need_paren = 1;
1797 letter = 0;
1799 if (letter == 'q' || letter == 'Q')
1800 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1802 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
1804 if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
1805 && SYMBOL_REF_DECL (XEXP (op, 1))
1806 && TREE_CODE (SYMBOL_REF_DECL (XEXP (op, 1))) == FUNCTION_DECL)
1808 fprintf (file, "%%code(");
1809 assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (XEXP (op, 1), 0)));
1810 fprintf (file, "+");
1811 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1812 fprintf (file, ")");
1814 else
1816 rl78_print_operand_1 (file, XEXP (op, 1), letter);
1817 fprintf (file, "+");
1818 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1821 else
1823 if (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1824 && SYMBOL_REF_DECL (XEXP (op, 0))
1825 && TREE_CODE (SYMBOL_REF_DECL (XEXP (op, 0))) == FUNCTION_DECL)
1827 fprintf (file, "%%code(");
1828 assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (XEXP (op, 0), 0)));
1829 fprintf (file, "+");
1830 rl78_print_operand_1 (file, XEXP (op, 1), letter);
1831 fprintf (file, ")");
1833 else
1835 rl78_print_operand_1 (file, XEXP (op, 0), letter);
1836 fprintf (file, "+");
1837 rl78_print_operand_1 (file, XEXP (op, 1), letter);
1840 if (need_paren)
1841 fprintf (file, ")");
1842 break;
1844 case SUBREG:
1845 if (GET_MODE (op) == HImode
1846 && SUBREG_BYTE (op) == 0)
1848 fprintf (file, "%%lo16(");
1849 rl78_print_operand_1 (file, SUBREG_REG (op), 0);
1850 fprintf (file, ")");
1852 else if (GET_MODE (op) == HImode
1853 && SUBREG_BYTE (op) == 2)
1855 fprintf (file, "%%hi16(");
1856 rl78_print_operand_1 (file, SUBREG_REG (op), 0);
1857 fprintf (file, ")");
1859 else
1861 fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
1863 break;
1865 case SYMBOL_REF:
1866 need_paren = 0;
1867 if (letter == 'H')
1869 fprintf (file, "%%hi16(");
1870 need_paren = 1;
1871 letter = 0;
1873 if (letter == 'h')
1875 fprintf (file, "%%lo16(");
1876 need_paren = 1;
1877 letter = 0;
1879 if (letter == 'e')
1881 fprintf (file, "%%hi8(");
1882 need_paren = 1;
1883 letter = 0;
1885 if (letter == 'q' || letter == 'Q')
1886 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1888 if (SYMBOL_REF_DECL (op) && TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL)
1890 fprintf (file, "%%code(");
1891 assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
1892 fprintf (file, ")");
1894 else
1895 assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
1896 if (need_paren)
1897 fprintf (file, ")");
1898 break;
1900 case CODE_LABEL:
1901 case LABEL_REF:
1902 output_asm_label (op);
1903 break;
1905 case LTU:
1906 if (letter == 'z')
1907 fprintf (file, "#comparison eliminated");
1908 else
1909 fprintf (file, letter == 'C' ? "nc" : "c");
1910 break;
1911 case LEU:
1912 if (letter == 'z')
1913 fprintf (file, "br");
1914 else
1915 fprintf (file, letter == 'C' ? "h" : "nh");
1916 break;
1917 case GEU:
1918 if (letter == 'z')
1919 fprintf (file, "br");
1920 else
1921 fprintf (file, letter == 'C' ? "c" : "nc");
1922 break;
1923 case GTU:
1924 if (letter == 'z')
1925 fprintf (file, "#comparison eliminated");
1926 else
1927 fprintf (file, letter == 'C' ? "nh" : "h");
1928 break;
1929 case EQ:
1930 if (letter == 'z')
1931 fprintf (file, "br");
1932 else
1933 fprintf (file, letter == 'C' ? "nz" : "z");
1934 break;
1935 case NE:
1936 if (letter == 'z')
1937 fprintf (file, "#comparison eliminated");
1938 else
1939 fprintf (file, letter == 'C' ? "z" : "nz");
1940 break;
1942 /* Note: these assume appropriate adjustments were made so that
1943 unsigned comparisons, which is all this chip has, will
1944 work. */
1945 case LT:
1946 if (letter == 'z')
1947 fprintf (file, "#comparison eliminated");
1948 else
1949 fprintf (file, letter == 'C' ? "nc" : "c");
1950 break;
1951 case LE:
1952 if (letter == 'z')
1953 fprintf (file, "br");
1954 else
1955 fprintf (file, letter == 'C' ? "h" : "nh");
1956 break;
1957 case GE:
1958 if (letter == 'z')
1959 fprintf (file, "br");
1960 else
1961 fprintf (file, letter == 'C' ? "c" : "nc");
1962 break;
1963 case GT:
1964 if (letter == 'z')
1965 fprintf (file, "#comparison eliminated");
1966 else
1967 fprintf (file, letter == 'C' ? "nh" : "h");
1968 break;
1970 default:
1971 fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
1972 break;
1976 #undef TARGET_PRINT_OPERAND
1977 #define TARGET_PRINT_OPERAND rl78_print_operand
1979 static void
1980 rl78_print_operand (FILE * file, rtx op, int letter)
1982 if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B')
1983 fprintf (file, "#");
1984 rl78_print_operand_1 (file, op, letter);
1987 #undef TARGET_TRAMPOLINE_INIT
1988 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
1990 /* Note that the RL78's addressing makes it very difficult to do
1991 trampolines on the stack. So, libgcc has a small pool of
1992 trampolines from which one is allocated to this task. */
1993 static void
1994 rl78_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
1996 rtx mov_addr, thunk_addr;
1997 rtx function = XEXP (DECL_RTL (fndecl), 0);
1999 mov_addr = adjust_address (m_tramp, HImode, 0);
2000 thunk_addr = gen_reg_rtx (HImode);
2002 function = force_reg (HImode, function);
2003 static_chain = force_reg (HImode, static_chain);
2005 emit_insn (gen_trampoline_init (thunk_addr, function, static_chain));
2006 emit_move_insn (mov_addr, thunk_addr);
2008 cfun->machine->trampolines_used = 1;
2011 #undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
2012 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS rl78_trampoline_adjust_address
2014 static rtx
2015 rl78_trampoline_adjust_address (rtx m_tramp)
2017 rtx x = gen_rtx_MEM (HImode, m_tramp);
2018 return x;
2021 /* Expander for cbranchqi4 and cbranchhi4. RL78 is missing some of
2022 the "normal" compares, specifically, it only has unsigned compares,
2023 so we must synthesize the missing ones. */
2024 void
2025 rl78_expand_compare (rtx *operands)
2027 if (GET_CODE (operands[2]) == MEM)
2028 operands[2] = copy_to_mode_reg (GET_MODE (operands[2]), operands[2]);
2033 /* Define this to 1 if you are debugging the peephole optimizers. */
2034 #define DEBUG_PEEP 0
2036 /* Predicate used to enable the peephole2 patterns in rl78-virt.md.
2037 The default "word" size is a byte so we can effectively use all the
2038 registers, but we want to do 16-bit moves whenever possible. This
2039 function determines when such a move is an option. */
2040 bool
2041 rl78_peep_movhi_p (rtx *operands)
2043 int i;
2044 rtx m, a;
2046 /* (set (op0) (op1))
2047 (set (op2) (op3)) */
2049 if (! rl78_virt_insns_ok ())
2050 return false;
2052 #if DEBUG_PEEP
2053 fprintf (stderr, "\033[33m");
2054 debug_rtx (operands[0]);
2055 debug_rtx (operands[1]);
2056 debug_rtx (operands[2]);
2057 debug_rtx (operands[3]);
2058 fprintf (stderr, "\033[0m");
2059 #endif
2061 /* You can move a constant to memory as QImode, but not HImode. */
2062 if (GET_CODE (operands[0]) == MEM
2063 && GET_CODE (operands[1]) != REG)
2065 #if DEBUG_PEEP
2066 fprintf (stderr, "no peep: move constant to memory\n");
2067 #endif
2068 return false;
2071 if (rtx_equal_p (operands[0], operands[3]))
2073 #if DEBUG_PEEP
2074 fprintf (stderr, "no peep: overlapping\n");
2075 #endif
2076 return false;
2079 for (i = 0; i < 2; i ++)
2081 if (GET_CODE (operands[i]) != GET_CODE (operands[i+2]))
2083 #if DEBUG_PEEP
2084 fprintf (stderr, "no peep: different codes\n");
2085 #endif
2086 return false;
2088 if (GET_MODE (operands[i]) != GET_MODE (operands[i+2]))
2090 #if DEBUG_PEEP
2091 fprintf (stderr, "no peep: different modes\n");
2092 #endif
2093 return false;
2096 switch (GET_CODE (operands[i]))
2098 case REG:
2099 /* LSB MSB */
2100 if (REGNO (operands[i]) + 1 != REGNO (operands[i+2])
2101 || GET_MODE (operands[i]) != QImode)
2103 #if DEBUG_PEEP
2104 fprintf (stderr, "no peep: wrong regnos %d %d %d\n",
2105 REGNO (operands[i]), REGNO (operands[i+2]),
2107 #endif
2108 return false;
2110 if (! rl78_hard_regno_mode_ok (REGNO (operands[i]), HImode))
2112 #if DEBUG_PEEP
2113 fprintf (stderr, "no peep: reg %d not HI\n", REGNO (operands[i]));
2114 #endif
2115 return false;
2117 break;
2119 case CONST_INT:
2120 break;
2122 case MEM:
2123 if (GET_MODE (operands[i]) != QImode)
2124 return false;
2125 if (MEM_ALIGN (operands[i]) < 16)
2126 return false;
2127 a = XEXP (operands[i], 0);
2128 if (GET_CODE (a) == CONST)
2129 a = XEXP (a, 0);
2130 if (GET_CODE (a) == PLUS)
2131 a = XEXP (a, 1);
2132 if (GET_CODE (a) == CONST_INT
2133 && INTVAL (a) & 1)
2135 #if DEBUG_PEEP
2136 fprintf (stderr, "no peep: misaligned mem %d\n", i);
2137 debug_rtx (operands[i]);
2138 #endif
2139 return false;
2141 m = adjust_address (operands[i], QImode, 1);
2142 if (! rtx_equal_p (m, operands[i+2]))
2144 #if DEBUG_PEEP
2145 fprintf (stderr, "no peep: wrong mem %d\n", i);
2146 debug_rtx (m);
2147 debug_rtx (operands[i+2]);
2148 #endif
2149 return false;
2151 break;
2153 default:
2154 #if DEBUG_PEEP
2155 fprintf (stderr, "no peep: wrong rtx %d\n", i);
2156 #endif
2157 return false;
2160 #if DEBUG_PEEP
2161 fprintf (stderr, "\033[32mpeep!\033[0m\n");
2162 #endif
2163 return true;
2166 /* Likewise, when a peephole is activated, this function helps compute
2167 the new operands. */
2168 void
2169 rl78_setup_peep_movhi (rtx *operands)
2171 int i;
2173 for (i = 0; i < 2; i ++)
2175 switch (GET_CODE (operands[i]))
2177 case REG:
2178 operands[i+4] = gen_rtx_REG (HImode, REGNO (operands[i]));
2179 break;
2181 case CONST_INT:
2182 operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char) INTVAL (operands[i+2])) * 256);
2183 break;
2185 case MEM:
2186 operands[i+4] = adjust_address (operands[i], HImode, 0);
2187 break;
2189 default:
2190 break;
2196 How Devirtualization works in the RL78 GCC port
2198 Background
2200 The RL78 is an 8-bit port with some 16-bit operations. It has 32
2201 bytes of register space, in four banks, memory-mapped. One bank is
2202 the "selected" bank and holds the registers used for primary
2203 operations. Since the registers are memory mapped, often you can
2204 still refer to the unselected banks via memory accesses.
2206 Virtual Registers
2208 The GCC port uses bank 0 as the "selected" registers (A, X, BC, etc)
2209 and refers to the other banks via their memory addresses, although
2210 they're treated as regular registers internally. These "virtual"
2211 registers are R8 through R23 (bank3 is reserved for asm-based
2212 interrupt handlers).
2214 There are four machine description files:
2216 rl78.md - common register-independent patterns and definitions
2217 rl78-expand.md - expanders
2218 rl78-virt.md - patterns that match BEFORE devirtualization
2219 rl78-real.md - patterns that match AFTER devirtualization
2221 At least through register allocation and reload, gcc is told that it
2222 can do pretty much anything - but may only use the virtual registers.
2223 GCC cannot properly create the varying addressing modes that the RL78
2224 supports in an efficient way.
2226 Sometime after reload, the RL78 backend "devirtualizes" the RTL. It
2227 uses the "valloc" attribute in rl78-virt.md for determining the rules
2228 by which it will replace virtual registers with real registers (or
2229 not) and how to make up addressing modes. For example, insns tagged
2230 with "ro1" have a single read-only parameter, which may need to be
2231 moved from memory/constant/vreg to a suitable real register. As part
2232 of devirtualization, a flag is toggled, disabling the rl78-virt.md
2233 patterns and enabling the rl78-real.md patterns. The new patterns'
2234 constraints are used to determine the real registers used. NOTE:
2235 patterns in rl78-virt.md essentially ignore the constrains and rely on
2236 predicates, where the rl78-real.md ones essentially ignore the
2237 predicates and rely on the constraints.
2239 The devirtualization pass is scheduled via the pass manager (despite
2240 being called "rl78_reorg") so it can be scheduled prior to var-track
2241 (the idea is to let gdb know about the new registers). Ideally, it
2242 would be scheduled right after pro/epilogue generation, so the
2243 post-reload optimizers could operate on the real registers, but when I
2244 tried that there were some issues building the target libraries.
2246 During devirtualization, a simple register move optimizer is run. It
2247 would be better to run a full CSE/propogation pass on it though, but
2248 that has not yet been attempted.
2251 #define DEBUG_ALLOC 0
2253 #define OP(x) (*recog_data.operand_loc[x])
2255 /* This array is used to hold knowledge about the contents of the
2256 real registers (A ... H), the memory-based registers (r8 ... r31)
2257 and the first NUM_STACK_LOCS words on the stack. We use this to
2258 avoid generating redundant move instructions.
2260 A value in the range 0 .. 31 indicates register A .. r31.
2261 A value in the range 32 .. 63 indicates stack slot (value - 32).
2262 A value of NOT_KNOWN indicates that the contents of that location
2263 are not known. */
2265 #define NUM_STACK_LOCS 32
2266 #define NOT_KNOWN 127
2268 static unsigned char content_memory [32 + NUM_STACK_LOCS];
2270 static unsigned char saved_update_index = NOT_KNOWN;
2271 static unsigned char saved_update_value;
2272 static machine_mode saved_update_mode;
2275 static inline void
2276 clear_content_memory (void)
2278 memset (content_memory, NOT_KNOWN, sizeof content_memory);
2279 if (dump_file)
2280 fprintf (dump_file, " clear content memory\n");
2281 saved_update_index = NOT_KNOWN;
2284 /* Convert LOC into an index into the content_memory array.
2285 If LOC cannot be converted, return NOT_KNOWN. */
2287 static unsigned char
2288 get_content_index (rtx loc)
2290 machine_mode mode;
2292 if (loc == NULL_RTX)
2293 return NOT_KNOWN;
2295 if (REG_P (loc))
2297 if (REGNO (loc) < 32)
2298 return REGNO (loc);
2299 return NOT_KNOWN;
2302 mode = GET_MODE (loc);
2304 if (! rl78_stack_based_mem (loc, mode))
2305 return NOT_KNOWN;
2307 loc = XEXP (loc, 0);
2309 if (REG_P (loc))
2310 /* loc = MEM (SP) */
2311 return 32;
2313 /* loc = MEM (PLUS (SP, INT)). */
2314 loc = XEXP (loc, 1);
2316 if (INTVAL (loc) < NUM_STACK_LOCS)
2317 return 32 + INTVAL (loc);
2319 return NOT_KNOWN;
2322 /* Return a string describing content INDEX in mode MODE.
2323 WARNING: Can return a pointer to a static buffer. */
2324 static const char *
2325 get_content_name (unsigned char index, machine_mode mode)
2327 static char buffer [128];
2329 if (index == NOT_KNOWN)
2330 return "Unknown";
2332 if (index > 31)
2333 sprintf (buffer, "stack slot %d", index - 32);
2334 else if (mode == HImode)
2335 sprintf (buffer, "%s%s",
2336 reg_names [index + 1], reg_names [index]);
2337 else
2338 return reg_names [index];
2340 return buffer;
2343 #if DEBUG_ALLOC
2345 static void
2346 display_content_memory (FILE * file)
2348 unsigned int i;
2350 fprintf (file, " Known memory contents:\n");
2352 for (i = 0; i < sizeof content_memory; i++)
2353 if (content_memory[i] != NOT_KNOWN)
2355 fprintf (file, " %s contains a copy of ", get_content_name (i, QImode));
2356 fprintf (file, "%s\n", get_content_name (content_memory [i], QImode));
2359 #endif
2361 static void
2362 update_content (unsigned char index, unsigned char val, machine_mode mode)
2364 unsigned int i;
2366 gcc_assert (index < sizeof content_memory);
2368 content_memory [index] = val;
2369 if (val != NOT_KNOWN)
2370 content_memory [val] = index;
2372 /* Make the entry in dump_file *before* VAL is increased below. */
2373 if (dump_file)
2375 fprintf (dump_file, " %s now contains ", get_content_name (index, mode));
2376 if (val == NOT_KNOWN)
2377 fprintf (dump_file, "Unknown\n");
2378 else
2379 fprintf (dump_file, "%s and vice versa\n", get_content_name (val, mode));
2382 if (mode == HImode)
2384 val = val == NOT_KNOWN ? val : val + 1;
2386 content_memory [index + 1] = val;
2387 if (val != NOT_KNOWN)
2389 content_memory [val] = index + 1;
2390 -- val;
2394 /* Any other places that had INDEX recorded as their contents are now invalid. */
2395 for (i = 0; i < sizeof content_memory; i++)
2397 if (i == index
2398 || (val != NOT_KNOWN && i == val))
2400 if (mode == HImode)
2401 ++ i;
2402 continue;
2405 if (content_memory[i] == index
2406 || (val != NOT_KNOWN && content_memory[i] == val))
2408 content_memory[i] = NOT_KNOWN;
2410 if (dump_file)
2411 fprintf (dump_file, " %s cleared\n", get_content_name (i, mode));
2413 if (mode == HImode)
2414 content_memory[++ i] = NOT_KNOWN;
2419 /* Record that LOC contains VALUE.
2420 For HImode locations record that LOC+1 contains VALUE+1.
2421 If LOC is not a register or stack slot, do nothing.
2422 If VALUE is not a register or stack slot, clear the recorded content. */
2424 static void
2425 record_content (rtx loc, rtx value)
2427 machine_mode mode;
2428 unsigned char index;
2429 unsigned char val;
2431 if ((index = get_content_index (loc)) == NOT_KNOWN)
2432 return;
2434 val = get_content_index (value);
2436 mode = GET_MODE (loc);
2438 if (val == index)
2440 if (! optimize)
2441 return;
2443 /* This should not happen when optimizing. */
2444 #if 1
2445 fprintf (stderr, "ASSIGNMENT of location to itself detected! [%s]\n",
2446 get_content_name (val, mode));
2447 return;
2448 #else
2449 gcc_unreachable ();
2450 #endif
2453 update_content (index, val, mode);
2456 /* Returns TRUE if LOC already contains a copy of VALUE. */
2458 static bool
2459 already_contains (rtx loc, rtx value)
2461 unsigned char index;
2462 unsigned char val;
2464 if ((index = get_content_index (loc)) == NOT_KNOWN)
2465 return false;
2467 if ((val = get_content_index (value)) == NOT_KNOWN)
2468 return false;
2470 if (content_memory [index] != val)
2471 return false;
2473 if (GET_MODE (loc) == HImode)
2474 return content_memory [index + 1] == val + 1;
2476 return true;
2479 bool
2480 rl78_es_addr (rtx addr)
2482 if (GET_CODE (addr) == MEM)
2483 addr = XEXP (addr, 0);
2484 if (GET_CODE (addr) != UNSPEC)
2485 return false;
2486 if (XINT (addr, 1) != UNS_ES_ADDR)
2487 return false;
2488 return true;
2492 rl78_es_base (rtx addr)
2494 if (GET_CODE (addr) == MEM)
2495 addr = XEXP (addr, 0);
2496 addr = XVECEXP (addr, 0, 1);
2497 if (GET_CODE (addr) == CONST
2498 && GET_CODE (XEXP (addr, 0)) == ZERO_EXTRACT)
2499 addr = XEXP (XEXP (addr, 0), 0);
2500 /* Mode doesn't matter here. */
2501 return gen_rtx_MEM (HImode, addr);
2504 /* Rescans an insn to see if it's recognized again. This is done
2505 carefully to ensure that all the constraint information is accurate
2506 for the newly matched insn. */
2507 static bool
2508 insn_ok_now (rtx_insn * insn)
2510 rtx pattern = PATTERN (insn);
2511 int i;
2513 INSN_CODE (insn) = -1;
2515 if (recog (pattern, insn, 0) > -1)
2517 extract_insn (insn);
2518 if (constrain_operands (1, get_preferred_alternatives (insn)))
2520 #if DEBUG_ALLOC
2521 fprintf (stderr, "\033[32m");
2522 debug_rtx (insn);
2523 fprintf (stderr, "\033[0m");
2524 #endif
2525 if (SET_P (pattern))
2526 record_content (SET_DEST (pattern), SET_SRC (pattern));
2528 /* We need to detect far addresses that haven't been
2529 converted to es/lo16 format. */
2530 for (i=0; i<recog_data.n_operands; i++)
2531 if (GET_CODE (OP (i)) == MEM
2532 && GET_MODE (XEXP (OP (i), 0)) == SImode
2533 && GET_CODE (XEXP (OP (i), 0)) != UNSPEC)
2534 return false;
2536 return true;
2539 else
2541 /* We need to re-recog the insn with virtual registers to get
2542 the operands. */
2543 cfun->machine->virt_insns_ok = 1;
2544 if (recog (pattern, insn, 0) > -1)
2546 extract_insn (insn);
2547 if (constrain_operands (0, get_preferred_alternatives (insn)))
2549 cfun->machine->virt_insns_ok = 0;
2550 return false;
2554 #if DEBUG_ALLOC
2555 fprintf (stderr, "\033[41;30m Unrecognized *virtual* insn \033[0m\n");
2556 debug_rtx (insn);
2557 #endif
2558 gcc_unreachable ();
2561 #if DEBUG_ALLOC
2562 fprintf (stderr, "\033[31m");
2563 debug_rtx (insn);
2564 fprintf (stderr, "\033[0m");
2565 #endif
2566 return false;
2569 #if DEBUG_ALLOC
2570 #define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__)
2571 #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__)
2572 #define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable ()
2573 #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; }
2574 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } FAILED
2575 #else
2576 #define FAILED gcc_unreachable ()
2577 #define MAYBE_OK(insn) if (insn_ok_now (insn)) return;
2578 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) return; FAILED
2579 #endif
2581 /* Registers into which we move the contents of virtual registers. */
2582 #define X gen_rtx_REG (QImode, X_REG)
2583 #define A gen_rtx_REG (QImode, A_REG)
2584 #define C gen_rtx_REG (QImode, C_REG)
2585 #define B gen_rtx_REG (QImode, B_REG)
2586 #define E gen_rtx_REG (QImode, E_REG)
2587 #define D gen_rtx_REG (QImode, D_REG)
2588 #define L gen_rtx_REG (QImode, L_REG)
2589 #define H gen_rtx_REG (QImode, H_REG)
2591 #define AX gen_rtx_REG (HImode, AX_REG)
2592 #define BC gen_rtx_REG (HImode, BC_REG)
2593 #define DE gen_rtx_REG (HImode, DE_REG)
2594 #define HL gen_rtx_REG (HImode, HL_REG)
2596 /* Returns TRUE if R is a virtual register. */
2597 static inline bool
2598 is_virtual_register (rtx r)
2600 return (GET_CODE (r) == REG
2601 && REGNO (r) >= 8
2602 && REGNO (r) < 32);
2605 /* In all these alloc routines, we expect the following: the insn
2606 pattern is unshared, the insn was previously recognized and failed
2607 due to predicates or constraints, and the operand data is in
2608 recog_data. */
2610 static int virt_insn_was_frame;
2612 /* Hook for all insns we emit. Re-mark them as FRAME_RELATED if
2613 needed. */
2614 static rtx
2615 EM2 (int line ATTRIBUTE_UNUSED, rtx r)
2617 #if DEBUG_ALLOC
2618 fprintf (stderr, "\033[36m%d: ", line);
2619 debug_rtx (r);
2620 fprintf (stderr, "\033[0m");
2621 #endif
2622 /*SCHED_GROUP_P (r) = 1;*/
2623 if (virt_insn_was_frame)
2624 RTX_FRAME_RELATED_P (r) = 1;
2625 return r;
2628 #define EM(x) EM2 (__LINE__, x)
2630 /* Return a suitable RTX for the low half of a __far address. */
2631 static rtx
2632 rl78_lo16 (rtx addr)
2634 rtx r;
2636 if (GET_CODE (addr) == SYMBOL_REF
2637 || GET_CODE (addr) == CONST)
2639 r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0));
2640 r = gen_rtx_CONST (HImode, r);
2642 else
2643 r = rl78_subreg (HImode, addr, SImode, 0);
2645 r = gen_es_addr (r);
2646 cfun->machine->uses_es = true;
2648 return r;
2651 /* Return a suitable RTX for the high half's lower byte of a __far address. */
2652 static rtx
2653 rl78_hi8 (rtx addr)
2655 if (GET_CODE (addr) == SYMBOL_REF
2656 || GET_CODE (addr) == CONST)
2658 rtx r = gen_rtx_ZERO_EXTRACT (QImode, addr, GEN_INT (8), GEN_INT (16));
2659 r = gen_rtx_CONST (QImode, r);
2660 return r;
2662 return rl78_subreg (QImode, addr, SImode, 2);
2665 static void
2666 add_postponed_content_update (rtx to, rtx value)
2668 unsigned char index;
2670 if ((index = get_content_index (to)) == NOT_KNOWN)
2671 return;
2673 gcc_assert (saved_update_index == NOT_KNOWN);
2674 saved_update_index = index;
2675 saved_update_value = get_content_index (value);
2676 saved_update_mode = GET_MODE (to);
2679 static void
2680 process_postponed_content_update (void)
2682 if (saved_update_index != NOT_KNOWN)
2684 update_content (saved_update_index, saved_update_value, saved_update_mode);
2685 saved_update_index = NOT_KNOWN;
2689 /* Generate and emit a move of (register) FROM into TO. if WHERE is not NULL
2690 then if BEFORE is true then emit the insn before WHERE, otherwise emit it
2691 after WHERE. If TO already contains FROM then do nothing. Returns TO if
2692 BEFORE is true, FROM otherwise. */
2693 static rtx
2694 gen_and_emit_move (rtx to, rtx from, rtx where, bool before)
2696 machine_mode mode = GET_MODE (to);
2698 if (optimize && before && already_contains (to, from))
2700 #if DEBUG_ALLOC
2701 display_content_memory (stderr);
2702 #endif
2703 if (dump_file)
2705 fprintf (dump_file, " Omit move of %s into ",
2706 get_content_name (get_content_index (from), mode));
2707 fprintf (dump_file, "%s as it already contains this value\n",
2708 get_content_name (get_content_index (to), mode));
2711 else
2713 rtx move = mode == QImode ? gen_movqi (to, from) : gen_movhi (to, from);
2715 EM (move);
2717 if (where == NULL_RTX)
2718 emit_insn (move);
2719 else if (before)
2720 emit_insn_before (move, where);
2721 else
2723 rtx note = find_reg_note (where, REG_EH_REGION, NULL_RTX);
2725 /* If necessary move REG_EH_REGION notes forward.
2726 cf. compiling gcc.dg/pr44545.c. */
2727 if (note != NULL_RTX)
2729 add_reg_note (move, REG_EH_REGION, XEXP (note, 0));
2730 remove_note (where, note);
2733 emit_insn_after (move, where);
2736 if (before)
2737 record_content (to, from);
2738 else
2739 add_postponed_content_update (to, from);
2742 return before ? to : from;
2745 /* If M is MEM(REG) or MEM(PLUS(REG,INT)) and REG is virtual then
2746 copy it into NEWBASE and return the updated MEM. Otherwise just
2747 return M. Any needed insns are emitted before BEFORE. */
2748 static rtx
2749 transcode_memory_rtx (rtx m, rtx newbase, rtx before)
2751 rtx base, index, addendr;
2752 int addend = 0;
2753 int need_es = 0;
2755 if (! MEM_P (m))
2756 return m;
2758 if (GET_MODE (XEXP (m, 0)) == SImode)
2760 rtx new_m;
2761 rtx seg = rl78_hi8 (XEXP (m, 0));
2763 if (!TARGET_ES0)
2765 emit_insn_before (EM (gen_movqi (A, seg)), before);
2766 emit_insn_before (EM (gen_movqi_to_es (A)), before);
2769 record_content (A, NULL_RTX);
2771 new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
2772 MEM_COPY_ATTRIBUTES (new_m, m);
2773 m = new_m;
2774 need_es = 1;
2777 characterize_address (XEXP (m, 0), & base, & index, & addendr);
2778 gcc_assert (index == NULL_RTX);
2780 if (base == NULL_RTX)
2781 return m;
2783 if (addendr && GET_CODE (addendr) == CONST_INT)
2784 addend = INTVAL (addendr);
2786 gcc_assert (REG_P (base));
2787 gcc_assert (REG_P (newbase));
2789 int limit = 256 - GET_MODE_SIZE (GET_MODE (m));
2791 if (REGNO (base) == SP_REG)
2793 if (addend >= 0 && addend <= limit)
2794 return m;
2797 /* BASE should be a virtual register. We copy it to NEWBASE. If
2798 the addend is out of range for DE/HL, we use AX to compute the full
2799 address. */
2801 if (addend < 0
2802 || (addend > limit && REGNO (newbase) != BC_REG)
2803 || (addendr
2804 && (GET_CODE (addendr) != CONST_INT)
2805 && ((REGNO (newbase) != BC_REG))
2808 /* mov ax, vreg
2809 add ax, #imm
2810 mov hl, ax */
2811 EM (emit_insn_before (gen_movhi (AX, base), before));
2812 EM (emit_insn_before (gen_addhi3 (AX, AX, addendr), before));
2813 EM (emit_insn_before (gen_movhi (newbase, AX), before));
2814 record_content (AX, NULL_RTX);
2815 record_content (newbase, NULL_RTX);
2817 base = newbase;
2818 addend = 0;
2819 addendr = 0;
2821 else
2823 base = gen_and_emit_move (newbase, base, before, true);
2826 if (addend)
2828 record_content (base, NULL_RTX);
2829 base = gen_rtx_PLUS (HImode, base, GEN_INT (addend));
2831 else if (addendr)
2833 record_content (base, NULL_RTX);
2834 base = gen_rtx_PLUS (HImode, base, addendr);
2837 if (need_es)
2839 m = change_address (m, GET_MODE (m), gen_es_addr (base));
2840 cfun->machine->uses_es = true;
2842 else
2843 m = change_address (m, GET_MODE (m), base);
2844 return m;
2847 /* Copy SRC to accumulator (A or AX), placing any generated insns
2848 before BEFORE. Returns accumulator RTX. */
2849 static rtx
2850 move_to_acc (int opno, rtx before)
2852 rtx src = OP (opno);
2853 machine_mode mode = GET_MODE (src);
2855 if (REG_P (src) && REGNO (src) < 2)
2856 return src;
2858 if (mode == VOIDmode)
2859 mode = recog_data.operand_mode[opno];
2861 return gen_and_emit_move (mode == QImode ? A : AX, src, before, true);
2864 static void
2865 force_into_acc (rtx src, rtx before)
2867 machine_mode mode = GET_MODE (src);
2868 rtx move;
2870 if (REG_P (src) && REGNO (src) < 2)
2871 return;
2873 move = mode == QImode ? gen_movqi (A, src) : gen_movhi (AX, src);
2875 EM (move);
2877 emit_insn_before (move, before);
2878 record_content (AX, NULL_RTX);
2881 /* Copy accumulator (A or AX) to DEST, placing any generated insns
2882 after AFTER. Returns accumulator RTX. */
2883 static rtx
2884 move_from_acc (unsigned int opno, rtx after)
2886 rtx dest = OP (opno);
2887 machine_mode mode = GET_MODE (dest);
2889 if (REG_P (dest) && REGNO (dest) < 2)
2890 return dest;
2892 return gen_and_emit_move (dest, mode == QImode ? A : AX, after, false);
2895 /* Copy accumulator (A or AX) to REGNO, placing any generated insns
2896 before BEFORE. Returns reg RTX. */
2897 static rtx
2898 move_acc_to_reg (rtx acc, int regno, rtx before)
2900 machine_mode mode = GET_MODE (acc);
2901 rtx reg;
2903 reg = gen_rtx_REG (mode, regno);
2905 return gen_and_emit_move (reg, acc, before, true);
2908 /* Copy SRC to X, placing any generated insns before BEFORE.
2909 Returns X RTX. */
2910 static rtx
2911 move_to_x (int opno, rtx before)
2913 rtx src = OP (opno);
2914 machine_mode mode = GET_MODE (src);
2915 rtx reg;
2917 if (mode == VOIDmode)
2918 mode = recog_data.operand_mode[opno];
2919 reg = (mode == QImode) ? X : AX;
2921 if (mode == QImode || ! is_virtual_register (OP (opno)))
2923 OP (opno) = move_to_acc (opno, before);
2924 OP (opno) = move_acc_to_reg (OP (opno), X_REG, before);
2925 return reg;
2928 return gen_and_emit_move (reg, src, before, true);
2931 /* Copy OP (opno) to H or HL, placing any generated insns before BEFORE.
2932 Returns H/HL RTX. */
2933 static rtx
2934 move_to_hl (int opno, rtx before)
2936 rtx src = OP (opno);
2937 machine_mode mode = GET_MODE (src);
2938 rtx reg;
2940 if (mode == VOIDmode)
2941 mode = recog_data.operand_mode[opno];
2942 reg = (mode == QImode) ? L : HL;
2944 if (mode == QImode || ! is_virtual_register (OP (opno)))
2946 OP (opno) = move_to_acc (opno, before);
2947 OP (opno) = move_acc_to_reg (OP (opno), L_REG, before);
2948 return reg;
2951 return gen_and_emit_move (reg, src, before, true);
2954 /* Copy OP (opno) to E or DE, placing any generated insns before BEFORE.
2955 Returns E/DE RTX. */
2956 static rtx
2957 move_to_de (int opno, rtx before)
2959 rtx src = OP (opno);
2960 machine_mode mode = GET_MODE (src);
2961 rtx reg;
2963 if (mode == VOIDmode)
2964 mode = recog_data.operand_mode[opno];
2966 reg = (mode == QImode) ? E : DE;
2968 if (mode == QImode || ! is_virtual_register (OP (opno)))
2970 OP (opno) = move_to_acc (opno, before);
2971 OP (opno) = move_acc_to_reg (OP (opno), E_REG, before);
2973 else
2975 gen_and_emit_move (reg, src, before, true);
2978 return reg;
2981 /* Devirtualize an insn of the form (SET (op) (unop (op))). */
2982 static void
2983 rl78_alloc_physical_registers_op1 (rtx_insn * insn)
2985 /* op[0] = func op[1] */
2987 /* We first try using A as the destination, then copying it
2988 back. */
2989 if (rtx_equal_p (OP (0), OP (1)))
2991 OP (0) =
2992 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
2994 else
2996 /* If necessary, load the operands into BC and HL.
2997 Check to see if we already have OP (0) in HL
2998 and if so, swap the order.
3000 It is tempting to perform this optimization when OP(0) does
3001 not hold a MEM, but this leads to bigger code in general.
3002 The problem is that if OP(1) holds a MEM then swapping it
3003 into BC means a BC-relative load is used and these are 3
3004 bytes long vs 1 byte for an HL load. */
3005 if (MEM_P (OP (0))
3006 && already_contains (HL, XEXP (OP (0), 0)))
3008 OP (0) = transcode_memory_rtx (OP (0), HL, insn);
3009 OP (1) = transcode_memory_rtx (OP (1), BC, insn);
3011 else
3013 OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3014 OP (1) = transcode_memory_rtx (OP (1), HL, insn);
3018 MAYBE_OK (insn);
3020 OP (0) = move_from_acc (0, insn);
3022 MAYBE_OK (insn);
3024 /* Try copying the src to acc first, then. This is for, for
3025 example, ZERO_EXTEND or NOT. */
3026 OP (1) = move_to_acc (1, insn);
3028 MUST_BE_OK (insn);
3031 /* Returns true if operand OPNUM contains a constraint of type CONSTRAINT.
3032 Assumes that the current insn has already been recognised and hence the
3033 constraint data has been filled in. */
3034 static bool
3035 has_constraint (unsigned int opnum, enum constraint_num constraint)
3037 const char * p = recog_data.constraints[opnum];
3039 /* No constraints means anything is accepted. */
3040 if (p == NULL || *p == 0 || *p == ',')
3041 return true;
3045 char c;
3046 unsigned int len;
3048 c = *p;
3049 len = CONSTRAINT_LEN (c, p);
3050 gcc_assert (len > 0);
3052 switch (c)
3054 case 0:
3055 case ',':
3056 return false;
3057 default:
3058 if (lookup_constraint (p) == constraint)
3059 return true;
3061 p += len;
3063 while (1);
3066 /* Devirtualize an insn of the form (SET (op) (binop (op) (op))). */
3067 static void
3068 rl78_alloc_physical_registers_op2 (rtx_insn * insn)
3070 rtx prev;
3071 rtx first;
3072 bool hl_used;
3073 int tmp_id;
3074 rtx saved_op1;
3076 if (rtx_equal_p (OP (0), OP (1)))
3078 if (MEM_P (OP (2)))
3080 OP (0) =
3081 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3082 OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3084 else
3086 OP (0) =
3087 OP (1) = transcode_memory_rtx (OP (1), HL, insn);
3088 OP (2) = transcode_memory_rtx (OP (2), DE, insn);
3091 else if (rtx_equal_p (OP (0), OP (2)))
3093 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3094 OP (0) =
3095 OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3097 else
3099 OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3100 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3101 OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3104 MAYBE_OK (insn);
3106 prev = prev_nonnote_nondebug_insn (insn);
3107 if (recog_data.constraints[1][0] == '%'
3108 && is_virtual_register (OP (1))
3109 && ! is_virtual_register (OP (2))
3110 && ! CONSTANT_P (OP (2)))
3112 rtx tmp = OP (1);
3113 OP (1) = OP (2);
3114 OP (2) = tmp;
3117 /* Make a note of whether (H)L is being used. It matters
3118 because if OP (2) also needs reloading, then we must take
3119 care not to corrupt HL. */
3120 hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1));
3122 /* If HL is not currently being used and dest == op1 then there are
3123 some possible optimizations available by reloading one of the
3124 operands into HL, before trying to use the accumulator. */
3125 if (optimize
3126 && ! hl_used
3127 && rtx_equal_p (OP (0), OP (1)))
3129 /* If op0 is a Ws1 type memory address then switching the base
3130 address register to HL might allow us to perform an in-memory
3131 operation. (eg for the INCW instruction).
3133 FIXME: Adding the move into HL is costly if this optimization is not
3134 going to work, so for now, make sure that we know that the new insn will
3135 match the requirements of the addhi3_real pattern. Really we ought to
3136 generate a candidate sequence, test that, and then install it if the
3137 results are good. */
3138 if (satisfies_constraint_Ws1 (OP (0))
3139 && has_constraint (0, CONSTRAINT_Wh1)
3140 && (satisfies_constraint_K (OP (2)) || satisfies_constraint_L (OP (2))))
3142 rtx base, index, addend, newbase;
3144 characterize_address (XEXP (OP (0), 0), & base, & index, & addend);
3145 gcc_assert (index == NULL_RTX);
3146 gcc_assert (REG_P (base) && REGNO (base) == SP_REG);
3148 /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */
3149 if (addend != NULL_RTX)
3151 newbase = gen_and_emit_move (HL, base, insn, true);
3152 record_content (newbase, NULL_RTX);
3153 newbase = gen_rtx_PLUS (HImode, newbase, addend);
3155 OP (0) = OP (1) = change_address (OP (0), VOIDmode, newbase);
3157 /* We do not want to fail here as this means that
3158 we have inserted useless insns into the stream. */
3159 MUST_BE_OK (insn);
3162 else if (REG_P (OP (0))
3163 && satisfies_constraint_Ws1 (OP (2))
3164 && has_constraint (2, CONSTRAINT_Wh1))
3166 rtx base, index, addend, newbase;
3168 characterize_address (XEXP (OP (2), 0), & base, & index, & addend);
3169 gcc_assert (index == NULL_RTX);
3170 gcc_assert (REG_P (base) && REGNO (base) == SP_REG);
3172 /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */
3173 if (addend != NULL_RTX)
3175 gen_and_emit_move (HL, base, insn, true);
3177 if (REGNO (OP (0)) != X_REG)
3179 OP (1) = move_to_acc (1, insn);
3180 OP (0) = move_from_acc (0, insn);
3183 record_content (HL, NULL_RTX);
3184 newbase = gen_rtx_PLUS (HImode, HL, addend);
3186 OP (2) = change_address (OP (2), VOIDmode, newbase);
3188 /* We do not want to fail here as this means that
3189 we have inserted useless insns into the stream. */
3190 MUST_BE_OK (insn);
3195 OP (0) = move_from_acc (0, insn);
3197 tmp_id = get_max_insn_count ();
3198 saved_op1 = OP (1);
3200 if (rtx_equal_p (OP (1), OP (2)))
3201 OP (2) = OP (1) = move_to_acc (1, insn);
3202 else
3203 OP (1) = move_to_acc (1, insn);
3205 MAYBE_OK (insn);
3207 /* If we omitted the move of OP1 into the accumulator (because
3208 it was already there from a previous insn), then force the
3209 generation of the move instruction now. We know that we
3210 are about to emit a move into HL (or DE) via AX, and hence
3211 our optimization to remove the load of OP1 is no longer valid. */
3212 if (tmp_id == get_max_insn_count ())
3213 force_into_acc (saved_op1, insn);
3215 /* We have to copy op2 to HL (or DE), but that involves AX, which
3216 already has a live value. Emit it before those insns. */
3218 if (prev)
3219 first = next_nonnote_nondebug_insn (prev);
3220 else
3221 for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3224 OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first);
3226 MUST_BE_OK (insn);
3229 /* Devirtualize an insn of the form SET (PC) (MEM/REG). */
3230 static void
3231 rl78_alloc_physical_registers_ro1 (rtx_insn * insn)
3233 OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3235 MAYBE_OK (insn);
3237 OP (0) = move_to_acc (0, insn);
3239 MUST_BE_OK (insn);
3242 /* Devirtualize a compare insn. */
3243 static void
3244 rl78_alloc_physical_registers_cmp (rtx_insn * insn)
3246 int tmp_id;
3247 rtx saved_op1;
3248 rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
3249 rtx first;
3251 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3252 OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3254 /* HI compares have to have OP (1) in AX, but QI
3255 compares do not, so it is worth checking here. */
3256 MAYBE_OK (insn);
3258 /* For an HImode compare, OP (1) must always be in AX.
3259 But if OP (1) is a REG (and not AX), then we can avoid
3260 a reload of OP (1) if we reload OP (2) into AX and invert
3261 the comparison. */
3262 if (REG_P (OP (1))
3263 && REGNO (OP (1)) != AX_REG
3264 && GET_MODE (OP (1)) == HImode
3265 && MEM_P (OP (2)))
3267 rtx cmp = XEXP (SET_SRC (PATTERN (insn)), 0);
3269 OP (2) = move_to_acc (2, insn);
3271 switch (GET_CODE (cmp))
3273 case EQ:
3274 case NE:
3275 break;
3276 case LTU: cmp = gen_rtx_GTU (HImode, OP (2), OP (1)); break;
3277 case GTU: cmp = gen_rtx_LTU (HImode, OP (2), OP (1)); break;
3278 case LEU: cmp = gen_rtx_GEU (HImode, OP (2), OP (1)); break;
3279 case GEU: cmp = gen_rtx_LEU (HImode, OP (2), OP (1)); break;
3281 case LT:
3282 case GT:
3283 case LE:
3284 case GE:
3285 #if DEBUG_ALLOC
3286 debug_rtx (insn);
3287 #endif
3288 default:
3289 gcc_unreachable ();
3292 if (GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
3293 PATTERN (insn) = gen_cbranchhi4_real (cmp, OP (2), OP (1), OP (3));
3294 else
3295 PATTERN (insn) = gen_cbranchhi4_real_inverted (cmp, OP (2), OP (1), OP (3));
3297 MUST_BE_OK (insn);
3300 /* Surprisingly, gcc can generate a comparison of a register with itself, but this
3301 should be handled by the second alternative of the cbranchhi_real pattern. */
3302 if (rtx_equal_p (OP (1), OP (2)))
3304 OP (1) = OP (2) = BC;
3305 MUST_BE_OK (insn);
3308 tmp_id = get_max_insn_count ();
3309 saved_op1 = OP (1);
3311 OP (1) = move_to_acc (1, insn);
3313 MAYBE_OK (insn);
3315 /* If we omitted the move of OP1 into the accumulator (because
3316 it was already there from a previous insn), then force the
3317 generation of the move instruction now. We know that we
3318 are about to emit a move into HL via AX, and hence our
3319 optimization to remove the load of OP1 is no longer valid. */
3320 if (tmp_id == get_max_insn_count ())
3321 force_into_acc (saved_op1, insn);
3323 /* We have to copy op2 to HL, but that involves the acc, which
3324 already has a live value. Emit it before those insns. */
3325 if (prev)
3326 first = next_nonnote_nondebug_insn (prev);
3327 else
3328 for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3330 OP (2) = move_to_hl (2, first);
3332 MUST_BE_OK (insn);
3335 /* Like op2, but AX = A * X. */
3336 static void
3337 rl78_alloc_physical_registers_umul (rtx_insn * insn)
3339 rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
3340 rtx first;
3341 int tmp_id;
3342 rtx saved_op1;
3344 OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3345 OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3346 OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3348 MAYBE_OK (insn);
3350 if (recog_data.constraints[1][0] == '%'
3351 && is_virtual_register (OP (1))
3352 && !is_virtual_register (OP (2))
3353 && !CONSTANT_P (OP (2)))
3355 rtx tmp = OP (1);
3356 OP (1) = OP (2);
3357 OP (2) = tmp;
3360 OP (0) = move_from_acc (0, insn);
3362 tmp_id = get_max_insn_count ();
3363 saved_op1 = OP (1);
3365 if (rtx_equal_p (OP (1), OP (2)))
3367 gcc_assert (GET_MODE (OP (2)) == QImode);
3368 /* The MULU instruction does not support duplicate arguments
3369 but we know that if we copy OP (2) to X it will do so via
3370 A and thus OP (1) will already be loaded into A. */
3371 OP (2) = move_to_x (2, insn);
3372 OP (1) = A;
3374 else
3375 OP (1) = move_to_acc (1, insn);
3377 MAYBE_OK (insn);
3379 /* If we omitted the move of OP1 into the accumulator (because
3380 it was already there from a previous insn), then force the
3381 generation of the move instruction now. We know that we
3382 are about to emit a move into HL (or DE) via AX, and hence
3383 our optimization to remove the load of OP1 is no longer valid. */
3384 if (tmp_id == get_max_insn_count ())
3385 force_into_acc (saved_op1, insn);
3387 /* We have to copy op2 to X, but that involves the acc, which
3388 already has a live value. Emit it before those insns. */
3390 if (prev)
3391 first = next_nonnote_nondebug_insn (prev);
3392 else
3393 for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3395 OP (2) = move_to_x (2, first);
3397 MUST_BE_OK (insn);
3400 static void
3401 rl78_alloc_address_registers_macax (rtx_insn * insn)
3403 int which, op;
3404 bool replace_in_op0 = false;
3405 bool replace_in_op1 = false;
3407 MAYBE_OK (insn);
3409 /* Two different MEMs are not allowed. */
3410 which = 0;
3411 for (op = 2; op >= 0; op --)
3413 if (MEM_P (OP (op)))
3415 if (op == 0 && replace_in_op0)
3416 continue;
3417 if (op == 1 && replace_in_op1)
3418 continue;
3420 switch (which)
3422 case 0:
3423 /* If we replace a MEM, make sure that we replace it for all
3424 occurrences of the same MEM in the insn. */
3425 replace_in_op0 = (op > 0 && rtx_equal_p (OP (op), OP (0)));
3426 replace_in_op1 = (op > 1 && rtx_equal_p (OP (op), OP (1)));
3428 OP (op) = transcode_memory_rtx (OP (op), HL, insn);
3429 if (op == 2
3430 && MEM_P (OP (op))
3431 && ((GET_CODE (XEXP (OP (op), 0)) == REG
3432 && REGNO (XEXP (OP (op), 0)) == SP_REG)
3433 || (GET_CODE (XEXP (OP (op), 0)) == PLUS
3434 && REGNO (XEXP (XEXP (OP (op), 0), 0)) == SP_REG)))
3436 emit_insn_before (gen_movhi (HL, gen_rtx_REG (HImode, SP_REG)), insn);
3437 OP (op) = replace_rtx (OP (op), gen_rtx_REG (HImode, SP_REG), HL);
3439 if (replace_in_op0)
3440 OP (0) = OP (op);
3441 if (replace_in_op1)
3442 OP (1) = OP (op);
3443 break;
3444 case 1:
3445 OP (op) = transcode_memory_rtx (OP (op), DE, insn);
3446 break;
3447 case 2:
3448 OP (op) = transcode_memory_rtx (OP (op), BC, insn);
3449 break;
3451 which ++;
3455 MUST_BE_OK (insn);
3458 static void
3459 rl78_alloc_address_registers_div (rtx_insn * insn)
3461 MUST_BE_OK (insn);
3464 /* Scan all insns and devirtualize them. */
3465 static void
3466 rl78_alloc_physical_registers (void)
3468 /* During most of the compile, gcc is dealing with virtual
3469 registers. At this point, we need to assign physical registers
3470 to the vitual ones, and copy in/out as needed. */
3472 rtx_insn *insn, *curr;
3473 enum attr_valloc valloc_method;
3475 for (insn = get_insns (); insn; insn = curr)
3477 int i;
3479 curr = next_nonnote_nondebug_insn (insn);
3481 if (INSN_P (insn)
3482 && (GET_CODE (PATTERN (insn)) == SET
3483 || GET_CODE (PATTERN (insn)) == CALL)
3484 && INSN_CODE (insn) == -1)
3486 if (GET_CODE (SET_SRC (PATTERN (insn))) == ASM_OPERANDS)
3487 continue;
3488 i = recog (PATTERN (insn), insn, 0);
3489 if (i == -1)
3491 debug_rtx (insn);
3492 gcc_unreachable ();
3494 INSN_CODE (insn) = i;
3498 cfun->machine->virt_insns_ok = 0;
3499 cfun->machine->real_insns_ok = 1;
3501 clear_content_memory ();
3503 for (insn = get_insns (); insn; insn = curr)
3505 rtx pattern;
3507 curr = insn ? next_nonnote_nondebug_insn (insn) : NULL;
3509 if (!INSN_P (insn))
3511 if (LABEL_P (insn))
3512 clear_content_memory ();
3514 continue;
3517 if (dump_file)
3518 fprintf (dump_file, "Converting insn %d\n", INSN_UID (insn));
3520 pattern = PATTERN (insn);
3521 if (GET_CODE (pattern) == PARALLEL)
3522 pattern = XVECEXP (pattern, 0, 0);
3523 if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL)
3524 clear_content_memory ();
3525 if (GET_CODE (pattern) != SET
3526 && GET_CODE (pattern) != CALL)
3527 continue;
3528 if (GET_CODE (pattern) == SET
3529 && GET_CODE (SET_SRC (pattern)) == ASM_OPERANDS)
3530 continue;
3532 valloc_method = get_attr_valloc (insn);
3534 PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
3536 if (valloc_method == VALLOC_MACAX)
3538 record_content (AX, NULL_RTX);
3539 record_content (BC, NULL_RTX);
3540 record_content (DE, NULL_RTX);
3542 else if (valloc_method == VALLOC_DIVHI)
3544 record_content (AX, NULL_RTX);
3545 record_content (BC, NULL_RTX);
3547 else if (valloc_method == VALLOC_DIVSI)
3549 record_content (AX, NULL_RTX);
3550 record_content (BC, NULL_RTX);
3551 record_content (DE, NULL_RTX);
3552 record_content (HL, NULL_RTX);
3555 if (insn_ok_now (insn))
3556 continue;
3558 INSN_CODE (insn) = -1;
3560 if (RTX_FRAME_RELATED_P (insn))
3561 virt_insn_was_frame = 1;
3562 else
3563 virt_insn_was_frame = 0;
3565 switch (valloc_method)
3567 case VALLOC_OP1:
3568 rl78_alloc_physical_registers_op1 (insn);
3569 break;
3570 case VALLOC_OP2:
3571 rl78_alloc_physical_registers_op2 (insn);
3572 break;
3573 case VALLOC_RO1:
3574 rl78_alloc_physical_registers_ro1 (insn);
3575 break;
3576 case VALLOC_CMP:
3577 rl78_alloc_physical_registers_cmp (insn);
3578 break;
3579 case VALLOC_UMUL:
3580 rl78_alloc_physical_registers_umul (insn);
3581 record_content (AX, NULL_RTX);
3582 break;
3583 case VALLOC_MACAX:
3584 /* Macro that clobbers AX. */
3585 rl78_alloc_address_registers_macax (insn);
3586 record_content (AX, NULL_RTX);
3587 record_content (BC, NULL_RTX);
3588 record_content (DE, NULL_RTX);
3589 break;
3590 case VALLOC_DIVSI:
3591 rl78_alloc_address_registers_div (insn);
3592 record_content (AX, NULL_RTX);
3593 record_content (BC, NULL_RTX);
3594 record_content (DE, NULL_RTX);
3595 record_content (HL, NULL_RTX);
3596 break;
3597 case VALLOC_DIVHI:
3598 rl78_alloc_address_registers_div (insn);
3599 record_content (AX, NULL_RTX);
3600 record_content (BC, NULL_RTX);
3601 break;
3602 default:
3603 gcc_unreachable ();
3606 if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL)
3607 clear_content_memory ();
3608 else
3609 process_postponed_content_update ();
3612 #if DEBUG_ALLOC
3613 fprintf (stderr, "\033[0m");
3614 #endif
3617 /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN.
3618 This function scans for uses of registers; the last use (i.e. first
3619 encounter when scanning backwards) triggers a REG_DEAD note if the
3620 reg was previously in DEAD[]. */
3621 static void
3622 rl78_note_reg_uses (char *dead, rtx s, rtx insn)
3624 const char *fmt;
3625 int i, r;
3626 enum rtx_code code;
3628 if (!s)
3629 return;
3631 code = GET_CODE (s);
3633 switch (code)
3635 /* Compare registers by number. */
3636 case REG:
3637 r = REGNO (s);
3638 if (dump_file)
3640 fprintf (dump_file, "note use reg %d size %d on insn %d\n",
3641 r, GET_MODE_SIZE (GET_MODE (s)), INSN_UID (insn));
3642 print_rtl_single (dump_file, s);
3644 if (dead [r])
3645 add_reg_note (insn, REG_DEAD, gen_rtx_REG (GET_MODE (s), r));
3646 for (i = 0; i < GET_MODE_SIZE (GET_MODE (s)); i ++)
3647 dead [r + i] = 0;
3648 return;
3650 /* These codes have no constituent expressions
3651 and are unique. */
3652 case SCRATCH:
3653 case CC0:
3654 case PC:
3655 return;
3657 case CONST_INT:
3658 case CONST_VECTOR:
3659 case CONST_DOUBLE:
3660 case CONST_FIXED:
3661 /* These are kept unique for a given value. */
3662 return;
3664 default:
3665 break;
3668 fmt = GET_RTX_FORMAT (code);
3670 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3672 if (fmt[i] == 'E')
3674 int j;
3675 for (j = XVECLEN (s, i) - 1; j >= 0; j--)
3676 rl78_note_reg_uses (dead, XVECEXP (s, i, j), insn);
3678 else if (fmt[i] == 'e')
3679 rl78_note_reg_uses (dead, XEXP (s, i), insn);
3683 /* Like the previous function, but scan for SETs instead. */
3684 static void
3685 rl78_note_reg_set (char *dead, rtx d, rtx insn)
3687 int r, i;
3689 if (GET_CODE (d) == MEM)
3690 rl78_note_reg_uses (dead, XEXP (d, 0), insn);
3692 if (GET_CODE (d) != REG)
3693 return;
3695 r = REGNO (d);
3696 if (dead [r])
3697 add_reg_note (insn, REG_UNUSED, gen_rtx_REG (GET_MODE (d), r));
3698 if (dump_file)
3699 fprintf (dump_file, "note set reg %d size %d\n", r, GET_MODE_SIZE (GET_MODE (d)));
3700 for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++)
3701 dead [r + i] = 1;
3704 /* This is a rather crude register death pass. Death status is reset
3705 at every jump or call insn. */
3706 static void
3707 rl78_calculate_death_notes (void)
3709 char dead[FIRST_PSEUDO_REGISTER];
3710 rtx insn, p, s, d;
3711 int i;
3713 memset (dead, 0, sizeof (dead));
3715 for (insn = get_last_insn ();
3716 insn;
3717 insn = prev_nonnote_nondebug_insn (insn))
3719 if (dump_file)
3721 fprintf (dump_file, "\n--------------------------------------------------");
3722 fprintf (dump_file, "\nDead:");
3723 for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
3724 if (dead[i])
3725 fprintf (dump_file, " %s", reg_names[i]);
3726 fprintf (dump_file, "\n");
3727 print_rtl_single (dump_file, insn);
3730 switch (GET_CODE (insn))
3732 case INSN:
3733 p = PATTERN (insn);
3734 if (GET_CODE (p) == PARALLEL)
3736 rtx q = XVECEXP (p, 0 ,1);
3738 /* This happens with the DIV patterns. */
3739 if (GET_CODE (q) == SET)
3741 s = SET_SRC (q);
3742 d = SET_DEST (q);
3743 rl78_note_reg_set (dead, d, insn);
3744 rl78_note_reg_uses (dead, s, insn);
3747 p = XVECEXP (p, 0, 0);
3750 switch (GET_CODE (p))
3752 case SET:
3753 s = SET_SRC (p);
3754 d = SET_DEST (p);
3755 rl78_note_reg_set (dead, d, insn);
3756 rl78_note_reg_uses (dead, s, insn);
3757 break;
3759 case USE:
3760 rl78_note_reg_uses (dead, p, insn);
3761 break;
3763 default:
3764 break;
3766 break;
3768 case JUMP_INSN:
3769 if (INSN_CODE (insn) == CODE_FOR_rl78_return)
3771 memset (dead, 1, sizeof (dead));
3772 /* We expect a USE just prior to this, which will mark
3773 the actual return registers. The USE will have a
3774 death note, but we aren't going to be modifying it
3775 after this pass. */
3776 break;
3778 case CALL_INSN:
3779 memset (dead, 0, sizeof (dead));
3780 break;
3782 default:
3783 break;
3785 if (dump_file)
3786 print_rtl_single (dump_file, insn);
3790 /* Helper function to reset the origins in RP and the age in AGE for
3791 all registers. */
3792 static void
3793 reset_origins (int *rp, int *age)
3795 int i;
3796 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3798 rp[i] = i;
3799 age[i] = 0;
3803 static void
3804 set_origin (rtx pat, rtx_insn * insn, int * origins, int * age)
3806 rtx src = SET_SRC (pat);
3807 rtx dest = SET_DEST (pat);
3808 int mb = GET_MODE_SIZE (GET_MODE (dest));
3809 int i;
3811 if (GET_CODE (dest) == REG)
3813 int dr = REGNO (dest);
3815 if (GET_CODE (src) == REG)
3817 int sr = REGNO (src);
3818 bool same = true;
3819 int best_age, best_reg;
3821 /* See if the copy is not needed. */
3822 for (i = 0; i < mb; i ++)
3823 if (origins[dr + i] != origins[sr + i])
3824 same = false;
3826 if (same)
3828 if (dump_file)
3829 fprintf (dump_file, "deleting because dest already has correct value\n");
3830 delete_insn (insn);
3831 return;
3834 if (dr < 8 || sr >= 8)
3836 int ar;
3838 best_age = -1;
3839 best_reg = -1;
3841 /* See if the copy can be made from another
3842 bank 0 register instead, instead of the
3843 virtual src register. */
3844 for (ar = 0; ar < 8; ar += mb)
3846 same = true;
3848 for (i = 0; i < mb; i ++)
3849 if (origins[ar + i] != origins[sr + i])
3850 same = false;
3852 /* The chip has some reg-reg move limitations. */
3853 if (mb == 1 && dr > 3)
3854 same = false;
3856 if (same)
3858 if (best_age == -1 || best_age > age[sr + i])
3860 best_age = age[sr + i];
3861 best_reg = sr;
3866 if (best_reg != -1)
3868 /* FIXME: copy debug info too. */
3869 SET_SRC (pat) = gen_rtx_REG (GET_MODE (src), best_reg);
3870 sr = best_reg;
3874 for (i = 0; i < mb; i++)
3876 origins[dr + i] = origins[sr + i];
3877 age[dr + i] = age[sr + i] + 1;
3880 else
3882 /* The destination is computed, its origin is itself. */
3883 if (dump_file)
3884 fprintf (dump_file, "resetting origin of r%d for %d byte%s\n",
3885 dr, mb, mb == 1 ? "" : "s");
3887 for (i = 0; i < mb; i ++)
3889 origins[dr + i] = dr + i;
3890 age[dr + i] = 0;
3894 /* Any registers marked with that reg as an origin are reset. */
3895 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3896 if (origins[i] >= dr && origins[i] < dr + mb)
3898 origins[i] = i;
3899 age[i] = 0;
3903 /* Special case - our MUL patterns uses AX and sometimes BC. */
3904 if (get_attr_valloc (insn) == VALLOC_MACAX)
3906 if (dump_file)
3907 fprintf (dump_file, "Resetting origin of AX/BC for MUL pattern.\n");
3909 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3910 if (i <= 3 || origins[i] <= 3)
3912 origins[i] = i;
3913 age[i] = 0;
3916 else if (get_attr_valloc (insn) == VALLOC_DIVHI)
3918 if (dump_file)
3919 fprintf (dump_file, "Resetting origin of AX/DE for DIVHI pattern.\n");
3921 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3922 if (i == A_REG
3923 || i == X_REG
3924 || i == D_REG
3925 || i == E_REG
3926 || origins[i] == A_REG
3927 || origins[i] == X_REG
3928 || origins[i] == D_REG
3929 || origins[i] == E_REG)
3931 origins[i] = i;
3932 age[i] = 0;
3935 else if (get_attr_valloc (insn) == VALLOC_DIVSI)
3937 if (dump_file)
3938 fprintf (dump_file, "Resetting origin of AX/BC/DE/HL for DIVSI pattern.\n");
3940 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3941 if (i <= 7 || origins[i] <= 7)
3943 origins[i] = i;
3944 age[i] = 0;
3948 if (GET_CODE (src) == ASHIFT
3949 || GET_CODE (src) == ASHIFTRT
3950 || GET_CODE (src) == LSHIFTRT)
3952 rtx count = XEXP (src, 1);
3954 if (GET_CODE (count) == REG)
3956 /* Special case - our pattern clobbers the count register. */
3957 int r = REGNO (count);
3959 if (dump_file)
3960 fprintf (dump_file, "Resetting origin of r%d for shift.\n", r);
3962 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3963 if (i == r || origins[i] == r)
3965 origins[i] = i;
3966 age[i] = 0;
3972 /* The idea behind this optimization is to look for cases where we
3973 move data from A to B to C, and instead move from A to B, and A to
3974 C. If B is a virtual register or memory, this is a big win on its
3975 own. If B turns out to be unneeded after this, it's a bigger win.
3976 For each register, we try to determine where it's value originally
3977 came from, if it's propogated purely through moves (and not
3978 computes). The ORIGINS[] array has the regno for the "origin" of
3979 the value in the [regno] it's indexed by. */
3980 static void
3981 rl78_propogate_register_origins (void)
3983 int origins[FIRST_PSEUDO_REGISTER];
3984 int age[FIRST_PSEUDO_REGISTER];
3985 int i;
3986 rtx_insn *insn, *ninsn = NULL;
3987 rtx pat;
3989 reset_origins (origins, age);
3991 for (insn = get_insns (); insn; insn = ninsn)
3993 ninsn = next_nonnote_nondebug_insn (insn);
3995 if (dump_file)
3997 fprintf (dump_file, "\n");
3998 fprintf (dump_file, "Origins:");
3999 for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
4000 if (origins[i] != i)
4001 fprintf (dump_file, " r%d=r%d", i, origins[i]);
4002 fprintf (dump_file, "\n");
4003 print_rtl_single (dump_file, insn);
4006 switch (GET_CODE (insn))
4008 case CODE_LABEL:
4009 case BARRIER:
4010 case CALL_INSN:
4011 case JUMP_INSN:
4012 reset_origins (origins, age);
4013 break;
4015 default:
4016 break;
4018 case INSN:
4019 pat = PATTERN (insn);
4021 if (GET_CODE (pat) == PARALLEL)
4023 rtx clobber = XVECEXP (pat, 0, 1);
4024 pat = XVECEXP (pat, 0, 0);
4025 if (GET_CODE (clobber) == CLOBBER
4026 && GET_CODE (XEXP (clobber, 0)) == REG)
4028 int cr = REGNO (XEXP (clobber, 0));
4029 int mb = GET_MODE_SIZE (GET_MODE (XEXP (clobber, 0)));
4030 if (dump_file)
4031 fprintf (dump_file, "reset origins of %d regs at %d\n", mb, cr);
4032 for (i = 0; i < mb; i++)
4034 origins[cr + i] = cr + i;
4035 age[cr + i] = 0;
4038 /* This happens with the DIV patterns. */
4039 else if (GET_CODE (clobber) == SET)
4041 set_origin (clobber, insn, origins, age);
4043 else
4044 break;
4047 if (GET_CODE (pat) == SET)
4049 set_origin (pat, insn, origins, age);
4051 else if (GET_CODE (pat) == CLOBBER
4052 && GET_CODE (XEXP (pat, 0)) == REG)
4054 if (REG_P (XEXP (pat, 0)))
4056 unsigned int reg = REGNO (XEXP (pat, 0));
4058 origins[reg] = reg;
4059 age[reg] = 0;
4066 /* Remove any SETs where the destination is unneeded. */
4067 static void
4068 rl78_remove_unused_sets (void)
4070 rtx_insn *insn, *ninsn = NULL;
4071 rtx dest;
4073 for (insn = get_insns (); insn; insn = ninsn)
4075 ninsn = next_nonnote_nondebug_insn (insn);
4077 rtx set = single_set (insn);
4078 if (set == NULL)
4079 continue;
4081 dest = SET_DEST (set);
4083 if (GET_CODE (dest) != REG || REGNO (dest) > 23)
4084 continue;
4086 if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
4088 if (dump_file)
4089 fprintf (dump_file, "deleting because the set register is never used.\n");
4090 delete_insn (insn);
4095 /* This is the top of the devritualization pass. */
4096 static void
4097 rl78_reorg (void)
4099 /* split2 only happens when optimizing, but we need all movSIs to be
4100 split now. */
4101 if (optimize <= 0)
4102 split_all_insns ();
4104 rl78_alloc_physical_registers ();
4106 if (dump_file)
4108 fprintf (dump_file, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n");
4109 print_rtl_with_bb (dump_file, get_insns (), 0);
4112 rl78_propogate_register_origins ();
4113 rl78_calculate_death_notes ();
4115 if (dump_file)
4117 fprintf (dump_file, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n");
4118 print_rtl_with_bb (dump_file, get_insns (), 0);
4119 fprintf (dump_file, "\n======================================================================\n");
4122 rl78_remove_unused_sets ();
4124 /* The code after devirtualizing has changed so much that at this point
4125 we might as well just rescan everything. Note that
4126 df_rescan_all_insns is not going to help here because it does not
4127 touch the artificial uses and defs. */
4128 df_finish_pass (true);
4129 if (optimize > 1)
4130 df_live_add_problem ();
4131 df_scan_alloc (NULL);
4132 df_scan_blocks ();
4134 if (optimize)
4135 df_analyze ();
4138 #undef TARGET_RETURN_IN_MEMORY
4139 #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory
4141 static bool
4142 rl78_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
4144 const HOST_WIDE_INT size = int_size_in_bytes (type);
4145 return (size == -1 || size > 8);
4149 #undef TARGET_RTX_COSTS
4150 #define TARGET_RTX_COSTS rl78_rtx_costs
4152 static bool
4153 rl78_rtx_costs (rtx x,
4154 machine_mode mode,
4155 int outer_code ATTRIBUTE_UNUSED,
4156 int opno ATTRIBUTE_UNUSED,
4157 int * total,
4158 bool speed ATTRIBUTE_UNUSED)
4160 int code = GET_CODE (x);
4162 if (code == IF_THEN_ELSE)
4164 *total = COSTS_N_INSNS (10);
4165 return true;
4168 if (mode == SImode)
4170 switch (code)
4172 case MULT:
4173 if (RL78_MUL_G14)
4174 *total = COSTS_N_INSNS (14);
4175 else if (RL78_MUL_G13)
4176 *total = COSTS_N_INSNS (29);
4177 else
4178 *total = COSTS_N_INSNS (500);
4179 return true;
4180 case PLUS:
4181 *total = COSTS_N_INSNS (8);
4182 return true;
4183 case ASHIFT:
4184 case ASHIFTRT:
4185 case LSHIFTRT:
4186 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
4188 switch (INTVAL (XEXP (x, 1)))
4190 case 0: *total = COSTS_N_INSNS (0); break;
4191 case 1: *total = COSTS_N_INSNS (6); break;
4192 case 2: case 3: case 4: case 5: case 6: case 7:
4193 *total = COSTS_N_INSNS (10); break;
4194 case 8: *total = COSTS_N_INSNS (6); break;
4195 case 9: case 10: case 11: case 12: case 13: case 14: case 15:
4196 *total = COSTS_N_INSNS (10); break;
4197 case 16: *total = COSTS_N_INSNS (3); break;
4198 case 17: case 18: case 19: case 20: case 21: case 22: case 23:
4199 *total = COSTS_N_INSNS (4); break;
4200 case 24: *total = COSTS_N_INSNS (4); break;
4201 case 25: case 26: case 27: case 28: case 29: case 30: case 31:
4202 *total = COSTS_N_INSNS (5); break;
4205 else
4206 *total = COSTS_N_INSNS (10+4*16);
4207 return true;
4210 return false;
4214 static GTY(()) section * saddr_section;
4215 static GTY(()) section * frodata_section;
4218 rl78_saddr_p (rtx x)
4220 const char * c;
4222 if (MEM_P (x))
4223 x = XEXP (x, 0);
4224 if (GET_CODE (x) == PLUS)
4225 x = XEXP (x, 0);
4226 if (GET_CODE (x) != SYMBOL_REF)
4227 return 0;
4229 c = XSTR (x, 0);
4230 if (memcmp (c, "@s.", 3) == 0)
4231 return 1;
4233 return 0;
4237 rl78_sfr_p (rtx x)
4239 if (MEM_P (x))
4240 x = XEXP (x, 0);
4241 if (GET_CODE (x) != CONST_INT)
4242 return 0;
4244 if ((INTVAL (x) & 0xFF00) != 0xFF00)
4245 return 0;
4247 return 1;
4250 #undef TARGET_STRIP_NAME_ENCODING
4251 #define TARGET_STRIP_NAME_ENCODING rl78_strip_name_encoding
4253 static const char *
4254 rl78_strip_name_encoding (const char * sym)
4256 while (1)
4258 if (*sym == '*')
4259 sym++;
4260 else if (*sym == '@' && sym[2] == '.')
4261 sym += 3;
4262 else
4263 return sym;
4267 /* Like rl78_strip_name_encoding, but does not strip leading asterisks. This
4268 is important if the stripped name is going to be passed to assemble_name()
4269 as that handles asterisk prefixed names in a special manner. */
4271 static const char *
4272 rl78_strip_nonasm_name_encoding (const char * sym)
4274 while (1)
4276 if (*sym == '@' && sym[2] == '.')
4277 sym += 3;
4278 else
4279 return sym;
4284 static int
4285 rl78_attrlist_to_encoding (tree list, tree decl ATTRIBUTE_UNUSED)
4287 while (list)
4289 if (is_attribute_p ("saddr", TREE_PURPOSE (list)))
4290 return 's';
4291 list = TREE_CHAIN (list);
4294 return 0;
4297 #define RL78_ATTRIBUTES(decl) \
4298 (TYPE_P (decl)) ? TYPE_ATTRIBUTES (decl) \
4299 : DECL_ATTRIBUTES (decl) \
4300 ? (DECL_ATTRIBUTES (decl)) \
4301 : TYPE_ATTRIBUTES (TREE_TYPE (decl))
4303 #undef TARGET_ENCODE_SECTION_INFO
4304 #define TARGET_ENCODE_SECTION_INFO rl78_encode_section_info
4306 static void
4307 rl78_encode_section_info (tree decl, rtx rtl, int first)
4309 rtx rtlname;
4310 const char * oldname;
4311 char encoding;
4312 char * newname;
4313 tree idp;
4314 tree type;
4315 tree rl78_attributes;
4317 if (!first)
4318 return;
4320 rtlname = XEXP (rtl, 0);
4322 if (GET_CODE (rtlname) == SYMBOL_REF)
4323 oldname = XSTR (rtlname, 0);
4324 else if (GET_CODE (rtlname) == MEM
4325 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
4326 oldname = XSTR (XEXP (rtlname, 0), 0);
4327 else
4328 gcc_unreachable ();
4330 type = TREE_TYPE (decl);
4331 if (type == error_mark_node)
4332 return;
4333 if (! DECL_P (decl))
4334 return;
4335 rl78_attributes = RL78_ATTRIBUTES (decl);
4337 encoding = rl78_attrlist_to_encoding (rl78_attributes, decl);
4339 if (encoding)
4341 newname = (char *) alloca (strlen (oldname) + 4);
4342 sprintf (newname, "@%c.%s", encoding, oldname);
4343 idp = get_identifier (newname);
4344 XEXP (rtl, 0) =
4345 gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
4346 SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl);
4347 SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl);
4351 #undef TARGET_ASM_INIT_SECTIONS
4352 #define TARGET_ASM_INIT_SECTIONS rl78_asm_init_sections
4354 static void
4355 rl78_asm_init_sections (void)
4357 saddr_section
4358 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
4359 "\t.section .saddr,\"aw\",@progbits");
4360 frodata_section
4361 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
4362 "\t.section .frodata,\"aw\",@progbits");
4365 #undef TARGET_ASM_SELECT_SECTION
4366 #define TARGET_ASM_SELECT_SECTION rl78_select_section
4368 static section *
4369 rl78_select_section (tree decl,
4370 int reloc,
4371 unsigned HOST_WIDE_INT align)
4373 int readonly = 1;
4375 switch (TREE_CODE (decl))
4377 case VAR_DECL:
4378 if (!TREE_READONLY (decl)
4379 || TREE_SIDE_EFFECTS (decl)
4380 || !DECL_INITIAL (decl)
4381 || (DECL_INITIAL (decl) != error_mark_node
4382 && !TREE_CONSTANT (DECL_INITIAL (decl))))
4383 readonly = 0;
4384 break;
4385 case CONSTRUCTOR:
4386 if (! TREE_CONSTANT (decl))
4387 readonly = 0;
4388 break;
4390 default:
4391 break;
4394 if (TREE_CODE (decl) == VAR_DECL)
4396 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
4398 if (name[0] == '@' && name[2] == '.')
4399 switch (name[1])
4401 case 's':
4402 return saddr_section;
4405 if (TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_FAR
4406 && readonly)
4408 return frodata_section;
4412 if (readonly)
4413 return TARGET_ES0 ? frodata_section : readonly_data_section;
4415 switch (categorize_decl_for_section (decl, reloc))
4417 case SECCAT_TEXT: return text_section;
4418 case SECCAT_DATA: return data_section;
4419 case SECCAT_BSS: return bss_section;
4420 case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
4421 default:
4422 return default_select_section (decl, reloc, align);
4426 void
4427 rl78_output_labelref (FILE *file, const char *str)
4429 const char *str2;
4431 str2 = targetm.strip_name_encoding (str);
4432 if (str2[0] != '.')
4433 fputs (user_label_prefix, file);
4434 fputs (str2, file);
4437 void
4438 rl78_output_aligned_common (FILE *stream,
4439 tree decl ATTRIBUTE_UNUSED,
4440 const char *name,
4441 int size, int align, int global)
4443 /* We intentionally don't use rl78_section_tag() here. */
4444 if (name[0] == '@' && name[2] == '.')
4446 const char *sec = 0;
4447 switch (name[1])
4449 case 's':
4450 switch_to_section (saddr_section);
4451 sec = ".saddr";
4452 break;
4454 if (sec)
4456 const char *name2;
4457 int p2align = 0;
4459 while (align > BITS_PER_UNIT)
4461 align /= 2;
4462 p2align ++;
4464 name2 = targetm.strip_name_encoding (name);
4465 if (global)
4466 fprintf (stream, "\t.global\t_%s\n", name2);
4467 fprintf (stream, "\t.p2align %d\n", p2align);
4468 fprintf (stream, "\t.type\t_%s,@object\n", name2);
4469 fprintf (stream, "\t.size\t_%s,%d\n", name2, size);
4470 fprintf (stream, "_%s:\n\t.zero\t%d\n", name2, size);
4471 return;
4475 if (!global)
4477 fprintf (stream, "\t.local\t");
4478 assemble_name (stream, name);
4479 fprintf (stream, "\n");
4481 fprintf (stream, "\t.comm\t");
4482 assemble_name (stream, name);
4483 fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT);
4486 #undef TARGET_INSERT_ATTRIBUTES
4487 #define TARGET_INSERT_ATTRIBUTES rl78_insert_attributes
4489 static void
4490 rl78_insert_attributes (tree decl, tree *attributes ATTRIBUTE_UNUSED)
4492 if (TARGET_ES0
4493 && TREE_CODE (decl) == VAR_DECL
4494 && TREE_READONLY (decl)
4495 && TREE_ADDRESSABLE (decl)
4496 && TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_GENERIC)
4498 tree type = TREE_TYPE (decl);
4499 tree attr = TYPE_ATTRIBUTES (type);
4500 int q = TYPE_QUALS_NO_ADDR_SPACE (type) | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_FAR);
4502 TREE_TYPE (decl) = build_type_attribute_qual_variant (type, attr, q);
4506 #undef TARGET_ASM_INTEGER
4507 #define TARGET_ASM_INTEGER rl78_asm_out_integer
4509 static bool
4510 rl78_asm_out_integer (rtx x, unsigned int size, int aligned_p)
4512 if (default_assemble_integer (x, size, aligned_p))
4513 return true;
4515 if (size == 4)
4517 assemble_integer_with_op (".long\t", x);
4518 return true;
4521 return false;
4524 #undef TARGET_UNWIND_WORD_MODE
4525 #define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode
4527 static machine_mode
4528 rl78_unwind_word_mode (void)
4530 return HImode;
4533 #ifndef USE_COLLECT2
4534 #undef TARGET_ASM_CONSTRUCTOR
4535 #define TARGET_ASM_CONSTRUCTOR rl78_asm_constructor
4536 #undef TARGET_ASM_DESTRUCTOR
4537 #define TARGET_ASM_DESTRUCTOR rl78_asm_destructor
4539 static void
4540 rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
4542 section *sec;
4544 if (priority != DEFAULT_INIT_PRIORITY)
4546 /* This section of the function is based upon code copied
4547 from: gcc/varasm.c:get_cdtor_priority_section(). */
4548 char buf[16];
4550 sprintf (buf, "%s.%.5u", is_ctor ? ".ctors" : ".dtors",
4551 MAX_INIT_PRIORITY - priority);
4552 sec = get_section (buf, 0, NULL);
4554 else
4555 sec = is_ctor ? ctors_section : dtors_section;
4557 assemble_addr_to_section (symbol, sec);
4560 static void
4561 rl78_asm_constructor (rtx symbol, int priority)
4563 rl78_asm_ctor_dtor (symbol, priority, true);
4566 static void
4567 rl78_asm_destructor (rtx symbol, int priority)
4569 rl78_asm_ctor_dtor (symbol, priority, false);
4571 #endif /* ! USE_COLLECT2 */
4573 /* Scan backwards through the insn chain looking to see if the flags
4574 have been set for a comparison of OP against OPERAND. Start with
4575 the insn *before* the current insn. */
4577 bool
4578 rl78_flags_already_set (rtx op, rtx operand)
4580 /* We only track the Z flag. */
4581 if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
4582 return false;
4584 /* This should not happen, but let's be paranoid. */
4585 if (current_output_insn == NULL_RTX)
4586 return false;
4588 rtx_insn *insn;
4589 bool res = false;
4591 for (insn = prev_nonnote_nondebug_insn (current_output_insn);
4592 insn != NULL_RTX;
4593 insn = prev_nonnote_nondebug_insn (insn))
4595 if (LABEL_P (insn))
4596 break;
4598 if (! INSN_P (insn))
4599 continue;
4601 /* Make sure that the insn can be recognized. */
4602 if (recog_memoized (insn) == -1)
4603 continue;
4605 enum attr_update_Z updated = get_attr_update_Z (insn);
4607 rtx set = single_set (insn);
4608 bool must_break = (set != NULL_RTX && rtx_equal_p (operand, SET_DEST (set)));
4610 switch (updated)
4612 case UPDATE_Z_NO:
4613 break;
4614 case UPDATE_Z_CLOBBER:
4615 must_break = true;
4616 break;
4617 case UPDATE_Z_UPDATE_Z:
4618 res = must_break;
4619 must_break = true;
4620 break;
4621 default:
4622 gcc_unreachable ();
4625 if (must_break)
4626 break;
4629 /* We have to re-recognize the current insn as the call(s) to
4630 get_attr_update_Z() above will have overwritten the recog_data cache. */
4631 recog_memoized (current_output_insn);
4632 cleanup_subreg_operands (current_output_insn);
4633 constrain_operands_cached (current_output_insn, 1);
4635 return res;
4638 const char *
4639 rl78_addsi3_internal (rtx * operands, unsigned int alternative)
4641 /* If we are adding in a constant symbolic address when -mes0
4642 is active then we know that the address must be <64K and
4643 that it is invalid to access anything above 64K relative to
4644 this address. So we can skip adding in the high bytes. */
4645 if (TARGET_ES0
4646 && GET_CODE (operands[2]) == SYMBOL_REF
4647 && TREE_CODE (SYMBOL_REF_DECL (operands[2])) == VAR_DECL
4648 && TREE_READONLY (SYMBOL_REF_DECL (operands[2]))
4649 && ! TREE_SIDE_EFFECTS (SYMBOL_REF_DECL (operands[2])))
4650 return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax";
4652 switch (alternative)
4654 case 0:
4655 case 1:
4656 return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax\n\tmovw ax, %H1\n\tsknc\n\tincw ax\n\taddw ax, %H2\n\tmovw %H0, ax";
4657 case 2:
4658 return "movw ax, %h1\n\taddw ax,%h2\n\tmovw bc, ax\n\tmovw ax, %H1\n\tsknc\n\tincw ax\n\taddw ax, %H2\n\tmovw %H0, ax\n\tmovw ax, bc\n\tmovw %h0, ax";
4659 default:
4660 gcc_unreachable ();
4665 #undef TARGET_PREFERRED_RELOAD_CLASS
4666 #define TARGET_PREFERRED_RELOAD_CLASS rl78_preferred_reload_class
4668 static reg_class_t
4669 rl78_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
4671 if (rclass == NO_REGS)
4672 rclass = V_REGS;
4674 return rclass;
4678 struct gcc_target targetm = TARGET_INITIALIZER;
4680 #include "gt-rl78.h"