1c5d1e1f6112dfec3950708f37c88b9bf03c1ef9
[platform/upstream/gcc.git] / gcc / config / rl78 / rl78.c
1 /* Subroutines used for code generation on Renesas RL78 processors.
2    Copyright (C) 2011-2019 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4
5    This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
21 #define IN_TARGET_CODE 1
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "df.h"
31 #include "memmodel.h"
32 #include "tm_p.h"
33 #include "stringpool.h"
34 #include "attribs.h"
35 #include "optabs.h"
36 #include "emit-rtl.h"
37 #include "recog.h"
38 #include "diagnostic-core.h"
39 #include "varasm.h"
40 #include "stor-layout.h"
41 #include "calls.h"
42 #include "output.h"
43 #include "insn-attr.h"
44 #include "explow.h"
45 #include "expr.h"
46 #include "reload.h"
47 #include "cfgrtl.h"
48 #include "langhooks.h"
49 #include "tree-pass.h"
50 #include "context.h"
51 #include "tm-constrs.h" /* for satisfies_constraint_*().  */
52 #include "builtins.h"
53
54 /* This file should be included last.  */
55 #include "target-def.h"
56 \f
57 static inline bool is_interrupt_func (const_tree decl);
58 static inline bool is_brk_interrupt_func (const_tree decl);
59 static void rl78_reorg (void);
60 static const char *rl78_strip_name_encoding (const char *);
61 static const char *rl78_strip_nonasm_name_encoding (const char *);
62 static section * rl78_select_section (tree, int, unsigned HOST_WIDE_INT);
63 \f
64
65 /* Debugging statements are tagged with DEBUG0 only so that they can
66    be easily enabled individually, by replacing the '0' with '1' as
67    needed.  */
68 #define DEBUG0 0
69 #define DEBUG1 1
70
71 /* REGISTER_NAMES has the names for individual 8-bit registers, but
72    these have the names we need to use when referring to 16-bit
73    register pairs.  */
74 static const char * const word_regnames[] =
75 {
76   "ax", "AX", "bc", "BC", "de", "DE", "hl", "HL",
77   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
78   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
79   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
80   "sp", "ap", "psw", "es", "cs"
81 };
82
83 /* used by rl78_addsi3_internal for formatting insns output */
84 static char fmt_buffer[1024];
85
86 /* Structure for G13 MDUC registers.  */
87 struct mduc_reg_type
88 {
89   unsigned int       address;
90   enum machine_mode  mode;
91 };
92
93 struct mduc_reg_type  mduc_regs[] =
94 {
95   {0xf00e8, E_QImode},
96   {0xffff0, E_HImode},
97   {0xffff2, E_HImode},
98   {0xf2224, E_HImode},
99   {0xf00e0, E_HImode},
100   {0xf00e2, E_HImode}
101 };
102
103 struct GTY(()) machine_function
104 {
105   /* If set, the rest of the fields have been computed.  */
106   int computed;
107   /* Which register pairs need to be pushed in the prologue.  */
108   int need_to_push [FIRST_PSEUDO_REGISTER / 2];
109
110   /* These fields describe the frame layout...  */
111   /* arg pointer */
112   /* 4 bytes for saved PC */
113   int framesize_regs;
114   /* frame pointer */
115   int framesize_locals;
116   int framesize_outgoing;
117   /* stack pointer */
118   int framesize;
119
120   /* If set, recog is allowed to match against the "real" patterns.  */
121   int real_insns_ok;
122   /* If set, recog is allowed to match against the "virtual" patterns.  */
123   int virt_insns_ok;
124   /* Set if the current function needs to clean up any trampolines.  */
125   int trampolines_used;
126   /* True if the ES register is used and hence
127      needs to be saved inside interrupt handlers.  */
128   bool uses_es;
129 };
130
131 /* This is our init_machine_status, as set in
132    rl78_option_override.  */
133 static struct machine_function *
134 rl78_init_machine_status (void)
135 {
136   struct machine_function *m;
137
138   m = ggc_cleared_alloc<machine_function> ();
139   m->virt_insns_ok = 1;
140
141   return m;
142 }
143
144 /* This pass converts virtual instructions using virtual registers, to
145    real instructions using real registers.  Rather than run it as
146    reorg, we reschedule it before vartrack to help with debugging.  */
147 namespace
148 {
149   const pass_data pass_data_rl78_devirt =
150     {
151       RTL_PASS, /* type */
152       "devirt", /* name */
153       OPTGROUP_NONE, /* optinfo_flags */
154       TV_MACH_DEP, /* tv_id */
155       0, /* properties_required */
156       0, /* properties_provided */
157       0, /* properties_destroyed */
158       0, /* todo_flags_start */
159       0, /* todo_flags_finish */
160     };
161
162   class pass_rl78_devirt : public rtl_opt_pass
163   {
164   public:
165     pass_rl78_devirt (gcc::context *ctxt)
166       : rtl_opt_pass (pass_data_rl78_devirt, ctxt)
167       {
168       }
169
170     /* opt_pass methods: */
171     virtual unsigned int execute (function *)
172     {
173       rl78_reorg ();
174       return 0;
175     }
176   };
177 } // anon namespace
178
179 rtl_opt_pass *
180 make_pass_rl78_devirt (gcc::context *ctxt)
181 {
182   return new pass_rl78_devirt (ctxt);
183 }
184
185 /* Redundant move elimination pass.  Must be run after the basic block
186    reordering pass for the best effect.  */
187
188 static unsigned int
189 move_elim_pass (void)
190 {
191   rtx_insn *insn, *ninsn;
192   rtx prev = NULL_RTX;
193
194   for (insn = get_insns (); insn; insn = ninsn)
195     {
196       rtx set;
197
198       ninsn = next_nonnote_nondebug_insn (insn);
199
200       if ((set = single_set (insn)) == NULL_RTX)
201         {
202           prev = NULL_RTX;
203           continue;
204         }
205
206       /* If we have two SET insns in a row (without anything
207          between them) and the source of the second one is the
208          destination of the first one, and vice versa, then we
209          can eliminate the second SET.  */
210       if (prev
211           && rtx_equal_p (SET_DEST (prev), SET_SRC (set))
212           && rtx_equal_p (SET_DEST (set), SET_SRC (prev))
213           /* ... and none of the operands are volatile.  */
214           && ! volatile_refs_p (SET_SRC (prev))
215           && ! volatile_refs_p (SET_DEST (prev))
216           && ! volatile_refs_p (SET_SRC (set))
217           && ! volatile_refs_p (SET_DEST (set)))
218         {
219           if (dump_file)
220             fprintf (dump_file, " Delete insn %d because it is redundant\n",
221                      INSN_UID (insn));
222
223           delete_insn (insn);
224           prev = NULL_RTX;
225         }
226       else
227         prev = set;
228     }
229
230   if (dump_file)
231     print_rtl_with_bb (dump_file, get_insns (), TDF_NONE);
232
233   return 0;
234 }
235
236 namespace
237 {
238   const pass_data pass_data_rl78_move_elim =
239     {
240       RTL_PASS, /* type */
241       "move_elim", /* name */
242       OPTGROUP_NONE, /* optinfo_flags */
243       TV_MACH_DEP, /* tv_id */
244       0, /* properties_required */
245       0, /* properties_provided */
246       0, /* properties_destroyed */
247       0, /* todo_flags_start */
248       0, /* todo_flags_finish */
249     };
250
251   class pass_rl78_move_elim : public rtl_opt_pass
252   {
253   public:
254     pass_rl78_move_elim (gcc::context *ctxt)
255       : rtl_opt_pass (pass_data_rl78_move_elim, ctxt)
256       {
257       }
258
259     /* opt_pass methods: */
260     virtual unsigned int execute (function *) { return move_elim_pass (); }
261   };
262 } // anon namespace
263
264 rtl_opt_pass *
265 make_pass_rl78_move_elim (gcc::context *ctxt)
266 {
267   return new pass_rl78_move_elim (ctxt);
268 }
269
270 #undef  TARGET_ASM_FILE_START
271 #define TARGET_ASM_FILE_START rl78_asm_file_start
272
273 static void
274 rl78_asm_file_start (void)
275 {
276   int i;
277
278   if (TARGET_G10)
279     {
280       /* The memory used is 0xffec8 to 0xffedf; real registers are in
281          0xffee0 to 0xffee7.  */
282       for (i = 8; i < 32; i++)
283         fprintf (asm_out_file, "r%d\t=\t0x%x\n", i, 0xffec0 + i);
284     }
285   else
286     {
287       for (i = 0; i < 8; i++)
288         {
289           fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i);
290           fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i);
291           fprintf (asm_out_file, "r%d\t=\t0x%x\n", 24 + i, 0xffee0 + i);
292         }
293     }
294
295   opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g);
296   struct register_pass_info rl78_devirt_info =
297     {
298       rl78_devirt_pass,
299       "pro_and_epilogue",
300       1,
301       PASS_POS_INSERT_BEFORE
302     };
303
304   opt_pass *rl78_move_elim_pass = make_pass_rl78_move_elim (g);
305   struct register_pass_info rl78_move_elim_info =
306     {
307       rl78_move_elim_pass,
308       "bbro",
309       1,
310       PASS_POS_INSERT_AFTER
311     };
312
313   register_pass (& rl78_devirt_info);
314   register_pass (& rl78_move_elim_info);
315 }
316
317 void
318 rl78_output_symbol_ref (FILE * file, rtx sym)
319 {
320   tree type = SYMBOL_REF_DECL (sym);
321   const char *str = XSTR (sym, 0);
322
323   if (str[0] == '*')
324     {
325       fputs (str + 1, file);
326     }
327   else
328     {
329       str = rl78_strip_nonasm_name_encoding (str);
330       if (type && TREE_CODE (type) == FUNCTION_DECL)
331         {
332           fprintf (file, "%%code(");
333           assemble_name (file, str);
334           fprintf (file, ")");
335         }
336       else
337         assemble_name (file, str);
338     }
339 }
340 \f
341 #undef  TARGET_OPTION_OVERRIDE
342 #define TARGET_OPTION_OVERRIDE          rl78_option_override
343
344 #define MUST_SAVE_MDUC_REGISTERS                        \
345   (TARGET_SAVE_MDUC_REGISTERS                           \
346    && (is_interrupt_func (NULL_TREE)) && RL78_MUL_G13)
347
348 static void
349 rl78_option_override (void)
350 {
351   flag_omit_frame_pointer = 1;
352   flag_no_function_cse = 1;
353   flag_split_wide_types = 0;
354
355   init_machine_status = rl78_init_machine_status;
356
357   if (TARGET_ALLREGS)
358     {
359       int i;
360
361       for (i = 24; i < 32; i++)
362         fixed_regs[i] = 0;
363     }
364
365   if (TARGET_ES0
366       && strcmp (lang_hooks.name, "GNU C")
367       && strcmp (lang_hooks.name, "GNU C11")
368       && strcmp (lang_hooks.name, "GNU C17")
369       && strcmp (lang_hooks.name, "GNU C2X")
370       && strcmp (lang_hooks.name, "GNU C89")
371       && strcmp (lang_hooks.name, "GNU C99")
372       /* Compiling with -flto results in a language of GNU GIMPLE being used... */
373       && strcmp (lang_hooks.name, "GNU GIMPLE"))
374     /* Address spaces are currently only supported by C.  */
375     error ("%<-mes0%> can only be used with C");
376
377   if (TARGET_SAVE_MDUC_REGISTERS && !(TARGET_G13 || RL78_MUL_G13))
378     warning (0, "mduc registers only saved for G13 target");
379
380   switch (rl78_cpu_type)
381     {
382     case CPU_UNINIT:
383       rl78_cpu_type = CPU_G14;
384       if (rl78_mul_type == MUL_UNINIT)
385         rl78_mul_type = MUL_NONE;
386       break;
387
388     case CPU_G10:
389       switch (rl78_mul_type)
390         {
391         case MUL_UNINIT: rl78_mul_type = MUL_NONE; break;
392         case MUL_NONE:   break;
393         case MUL_G13:    error ("%<-mmul=g13%> cannot be used with "
394                                 "%<-mcpu=g10%>"); break;
395         case MUL_G14:    error ("%<-mmul=g14%> cannot be used with "
396                                 "%<-mcpu=g10%>"); break;
397         }
398       break;
399
400     case CPU_G13:
401       switch (rl78_mul_type)
402         {
403         case MUL_UNINIT: rl78_mul_type = MUL_G13; break;
404         case MUL_NONE:   break;
405         case MUL_G13:   break;
406           /* The S2 core does not have mul/div instructions.  */
407         case MUL_G14:   error ("%<-mmul=g14%> cannot be used with "
408                                "%<-mcpu=g13%>"); break;
409         }
410       break;
411
412     case CPU_G14:
413       switch (rl78_mul_type)
414         {
415         case MUL_UNINIT: rl78_mul_type = MUL_G14; break;
416         case MUL_NONE:   break;
417         case MUL_G14:   break;
418         /* The G14 core does not have the hardware multiply peripheral used by the
419            G13 core, hence you cannot use G13 multipliy routines on G14 hardware.  */
420         case MUL_G13:   error ("%<-mmul=g13%> cannot be used with "
421                                "%<-mcpu=g14%>"); break;
422         }
423       break;
424     }
425 }
426
427 /* Most registers are 8 bits.  Some are 16 bits because, for example,
428    gcc doesn't like dealing with $FP as a register pair (the second
429    half of $fp is also 2 to keep reload happy wrt register pairs, but
430    no register class includes it).  This table maps register numbers
431    to size in bytes.  */
432 static const int register_sizes[] =
433 {
434   1, 1, 1, 1, 1, 1, 1, 1,
435   1, 1, 1, 1, 1, 1, 1, 1,
436   1, 1, 1, 1, 1, 1, 2, 2,
437   1, 1, 1, 1, 1, 1, 1, 1,
438   2, 2, 1, 1, 1
439 };
440
441 /* Predicates used in the MD patterns.  This one is true when virtual
442    insns may be matched, which typically means before (or during) the
443    devirt pass.  */
444 bool
445 rl78_virt_insns_ok (void)
446 {
447   if (cfun)
448     return cfun->machine->virt_insns_ok;
449   return true;
450 }
451
452 /* Predicates used in the MD patterns.  This one is true when real
453    insns may be matched, which typically means after (or during) the
454    devirt pass.  */
455 bool
456 rl78_real_insns_ok (void)
457 {
458   if (cfun)
459     return cfun->machine->real_insns_ok;
460   return false;
461 }
462
463 #undef TARGET_HARD_REGNO_NREGS
464 #define TARGET_HARD_REGNO_NREGS rl78_hard_regno_nregs
465
466 static unsigned int
467 rl78_hard_regno_nregs (unsigned int regno, machine_mode mode)
468 {
469   int rs = register_sizes[regno];
470   if (rs < 1)
471     rs = 1;
472   return ((GET_MODE_SIZE (mode) + rs - 1) / rs);
473 }
474
475 #undef TARGET_HARD_REGNO_MODE_OK
476 #define TARGET_HARD_REGNO_MODE_OK rl78_hard_regno_mode_ok
477
478 static bool
479 rl78_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
480 {
481   int s = GET_MODE_SIZE (mode);
482
483   if (s < 1)
484     return false;
485   /* These are not to be used by gcc.  */
486   if (regno == 23 || regno == ES_REG || regno == CS_REG)
487     return false;
488   /* $fp can always be accessed as a 16-bit value.  */
489   if (regno == FP_REG && s == 2)
490     return true;
491   if (regno < SP_REG)
492     {
493       /* Since a reg-reg move is really a reg-mem move, we must
494          enforce alignment.  */
495       if (s > 1 && (regno % 2))
496         return false;
497       return true;
498     }
499   if (s == CC_REGNUM)
500     return (mode == BImode);
501   /* All other registers must be accessed in their natural sizes.  */
502   if (s == register_sizes [regno])
503     return true;
504   return false;
505 }
506
507 #undef TARGET_MODES_TIEABLE_P
508 #define TARGET_MODES_TIEABLE_P rl78_modes_tieable_p
509
510 static bool
511 rl78_modes_tieable_p (machine_mode mode1, machine_mode mode2)
512 {
513   return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
514            || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
515           == (GET_MODE_CLASS (mode2) == MODE_FLOAT
516               || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
517 }
518
519 /* Simplify_gen_subreg() doesn't handle memory references the way we
520    need it to below, so we use this function for when we must get a
521    valid subreg in a "natural" state.  */
522 static rtx
523 rl78_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
524 {
525   if (GET_CODE (r) == MEM)
526     return adjust_address (r, mode, byte);
527   else
528     return simplify_gen_subreg (mode, r, omode, byte);
529 }
530
531 /* Used by movsi.  Split SImode moves into two HImode moves, using
532    appropriate patterns for the upper and lower halves of symbols.  */
533 void
534 rl78_expand_movsi (rtx *operands)
535 {
536   rtx op00, op02, op10, op12;
537
538   op00 = rl78_subreg (HImode, operands[0], SImode, 0);
539   op02 = rl78_subreg (HImode, operands[0], SImode, 2);
540   if (GET_CODE (operands[1]) == CONST
541       || GET_CODE (operands[1]) == SYMBOL_REF)
542     {
543       op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
544       op10 = gen_rtx_CONST (HImode, op10);
545       op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
546       op12 = gen_rtx_CONST (HImode, op12);
547     }
548   else
549     {
550       op10 = rl78_subreg (HImode, operands[1], SImode, 0);
551       op12 = rl78_subreg (HImode, operands[1], SImode, 2);
552     }
553
554   if (rtx_equal_p (operands[0], operands[1]))
555     ;
556   else if (rtx_equal_p (op00, op12))
557     {
558       emit_move_insn (op02, op12);
559       emit_move_insn (op00, op10);
560     }
561   else
562     {
563       emit_move_insn (op00, op10);
564       emit_move_insn (op02, op12);
565     }
566 }
567
568 /* Generate code to move an SImode value.  */
569 void
570 rl78_split_movsi (rtx *operands, machine_mode omode)
571 {
572   rtx op00, op02, op10, op12;
573
574   op00 = rl78_subreg (HImode, operands[0], omode, 0);
575   op02 = rl78_subreg (HImode, operands[0], omode, 2);
576
577   if (GET_CODE (operands[1]) == CONST
578       || GET_CODE (operands[1]) == SYMBOL_REF)
579     {
580       op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
581       op10 = gen_rtx_CONST (HImode, op10);
582       op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
583       op12 = gen_rtx_CONST (HImode, op12);
584     }
585   else
586     {
587       op10 = rl78_subreg (HImode, operands[1], omode, 0);
588       op12 = rl78_subreg (HImode, operands[1], omode, 2);
589     }
590
591   if (rtx_equal_p (operands[0], operands[1]))
592     ;
593   else if (rtx_equal_p (op00, op12))
594     {
595       operands[2] = op02;
596       operands[4] = op12;
597       operands[3] = op00;
598       operands[5] = op10;
599     }
600   else
601     {
602       operands[2] = op00;
603       operands[4] = op10;
604       operands[3] = op02;
605       operands[5] = op12;
606     }
607 }
608
609 void
610 rl78_split_movdi (rtx *operands, enum machine_mode omode)
611 {
612     rtx op00, op04, op10, op14;
613     op00 = rl78_subreg (SImode, operands[0], omode, 0);
614     op04 = rl78_subreg (SImode, operands[0], omode, 4);
615     op10 = rl78_subreg (SImode, operands[1], omode, 0);
616     op14 = rl78_subreg (SImode, operands[1], omode, 4);
617     emit_insn (gen_movsi (op00, op10));
618     emit_insn (gen_movsi (op04, op14));
619 }
620
621 /* Used by various two-operand expanders which cannot accept all
622    operands in the "far" namespace.  Force some such operands into
623    registers so that each pattern has at most one far operand.  */
624 int
625 rl78_force_nonfar_2 (rtx *operands, rtx (*gen)(rtx,rtx))
626 {
627   int did = 0;
628   rtx temp_reg = NULL;
629
630   /* FIXME: in the future, be smarter about only doing this if the
631      other operand is also far, assuming the devirtualizer can also
632      handle that.  */
633   if (rl78_far_p (operands[0]))
634     {
635       temp_reg = operands[0];
636       operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
637       did = 1;
638     }
639   if (!did)
640     return 0;
641
642   emit_insn (gen (operands[0], operands[1]));
643   if (temp_reg)
644     emit_move_insn (temp_reg, operands[0]);
645   return 1;
646 }
647
648 /* Likewise, but for three-operand expanders.  */
649 int
650 rl78_force_nonfar_3 (rtx *operands, rtx (*gen)(rtx,rtx,rtx))
651 {
652   int did = 0;
653   rtx temp_reg = NULL;
654
655   /* FIXME: Likewise.  */
656   if (rl78_far_p (operands[1]))
657     {
658       rtx temp_reg = gen_reg_rtx (GET_MODE (operands[1]));
659       emit_move_insn (temp_reg, operands[1]);
660       operands[1] = temp_reg;
661       did = 1;
662     }
663   if (rl78_far_p (operands[0]))
664     {
665       temp_reg = operands[0];
666       operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
667       did = 1;
668     }
669   if (!did)
670     return 0;
671
672   emit_insn (gen (operands[0], operands[1], operands[2]));
673   if (temp_reg)
674     emit_move_insn (temp_reg, operands[0]);
675   return 1;
676 }
677
678 int
679 rl78_one_far_p (rtx *operands, int n)
680 {
681   rtx which = NULL;
682   int i, c = 0;
683
684   for (i = 0; i < n; i ++)
685     if (rl78_far_p (operands[i]))
686       {
687         if (which == NULL)
688           which = operands[i];
689         else if (rtx_equal_p (operands[i], which))
690           continue;
691         c ++;
692       }
693   return c <= 1;
694 }
695
696 #undef  TARGET_CAN_ELIMINATE
697 #define TARGET_CAN_ELIMINATE            rl78_can_eliminate
698
699 static bool
700 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUSED)
701 {
702   return true;
703 }
704
705 /* Returns true if the given register needs to be saved by the
706    current function.  */
707 static bool
708 need_to_save (unsigned int regno)
709 {
710   if (is_interrupt_func (cfun->decl))
711     {
712       /* We don't know what devirt will need */
713       if (regno < 8)
714         return true;
715
716        /* We don't need to save registers that have
717           been reserved for interrupt handlers.  */
718       if (regno > 23)
719         return false;
720
721       /* If the handler is a non-leaf function then it may call
722          non-interrupt aware routines which will happily clobber
723          any call_used registers, so we have to preserve them.
724          We do not have to worry about the frame pointer register
725          though, as that is handled below.  */
726       if (!crtl->is_leaf && call_used_regs[regno] && regno < 22)
727         return true;
728
729       /* Otherwise we only have to save a register, call_used
730          or not, if it is used by this handler.  */
731       return df_regs_ever_live_p (regno);
732     }
733
734   if (regno == FRAME_POINTER_REGNUM
735       && (frame_pointer_needed || df_regs_ever_live_p (regno)))
736     return true;
737   if (fixed_regs[regno])
738     return false;
739   if (crtl->calls_eh_return)
740     return true;
741   if (df_regs_ever_live_p (regno)
742       && !call_used_regs[regno])
743     return true;
744   return false;
745 }
746
747 /* We use this to wrap all emitted insns in the prologue.  */
748 static rtx
749 F (rtx x)
750 {
751   RTX_FRAME_RELATED_P (x) = 1;
752   return x;
753 }
754
755 /* Compute all the frame-related fields in our machine_function
756    structure.  */
757 static void
758 rl78_compute_frame_info (void)
759 {
760   int i;
761
762   cfun->machine->computed = 1;
763   cfun->machine->framesize_regs = 0;
764   cfun->machine->framesize_locals = get_frame_size ();
765   cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
766
767   for (i = 0; i < 16; i ++)
768     if (need_to_save (i * 2) || need_to_save (i * 2 + 1))
769       {
770         cfun->machine->need_to_push [i] = 1;
771         cfun->machine->framesize_regs += 2;
772       }
773     else
774       cfun->machine->need_to_push [i] = 0;
775
776   if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
777     cfun->machine->framesize_locals ++;
778
779   cfun->machine->framesize = (cfun->machine->framesize_regs
780                               + cfun->machine->framesize_locals
781                               + cfun->machine->framesize_outgoing);
782 }
783 \f
784 /* Returns true if the provided function has the specified attribute.  */
785 static inline bool
786 has_func_attr (const_tree decl, const char * func_attr)
787 {
788   if (decl == NULL_TREE)
789     decl = current_function_decl;
790
791   return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
792 }
793
794 /* Returns true if the provided function has the "interrupt" attribute.  */
795 static inline bool
796 is_interrupt_func (const_tree decl)
797 {
798   return has_func_attr (decl, "interrupt") || has_func_attr (decl, "brk_interrupt");
799 }
800
801 /* Returns true if the provided function has the "brk_interrupt" attribute.  */
802 static inline bool
803 is_brk_interrupt_func (const_tree decl)
804 {
805   return has_func_attr (decl, "brk_interrupt");
806 }
807
808 /* Check "interrupt" attributes.  */
809 static tree
810 rl78_handle_func_attribute (tree * node,
811                             tree   name,
812                             tree   args ATTRIBUTE_UNUSED,
813                             int    flags ATTRIBUTE_UNUSED,
814                             bool * no_add_attrs)
815 {
816   gcc_assert (DECL_P (* node));
817
818   if (TREE_CODE (* node) != FUNCTION_DECL)
819     {
820       warning (OPT_Wattributes, "%qE attribute only applies to functions",
821                name);
822       * no_add_attrs = true;
823     }
824
825   /* FIXME: We ought to check that the interrupt and exception
826      handler attributes have been applied to void functions.  */
827   return NULL_TREE;
828 }
829
830 /* Check "naked" attributes.  */
831 static tree
832 rl78_handle_naked_attribute (tree * node,
833                              tree   name ATTRIBUTE_UNUSED,
834                              tree   args,
835                              int    flags ATTRIBUTE_UNUSED,
836                              bool * no_add_attrs)
837 {
838   gcc_assert (DECL_P (* node));
839   gcc_assert (args == NULL_TREE);
840
841   if (TREE_CODE (* node) != FUNCTION_DECL)
842     {
843       warning (OPT_Wattributes, "naked attribute only applies to functions");
844       * no_add_attrs = true;
845     }
846
847   /* Disable warnings about this function - eg reaching the end without
848      seeing a return statement - because the programmer is doing things
849      that gcc does not know about.  */
850   TREE_NO_WARNING (* node) = 1;
851
852   return NULL_TREE;
853 }
854
855 /* Check "saddr" attributes.  */
856 static tree
857 rl78_handle_saddr_attribute (tree * node,
858                              tree   name,
859                              tree   args ATTRIBUTE_UNUSED,
860                              int    flags ATTRIBUTE_UNUSED,
861                              bool * no_add_attrs)
862 {
863   gcc_assert (DECL_P (* node));
864
865   if (TREE_CODE (* node) == FUNCTION_DECL)
866     {
867       warning (OPT_Wattributes, "%qE attribute doesn%'t apply to functions",
868                name);
869       * no_add_attrs = true;
870     }
871
872   return NULL_TREE;
873 }
874
875 /* Check "vector" attribute.  */
876
877 static tree
878 rl78_handle_vector_attribute (tree * node,
879                             tree   name,
880                             tree   args,
881                             int    flags ATTRIBUTE_UNUSED,
882                             bool * no_add_attrs)
883 {
884   gcc_assert (DECL_P (* node));
885   gcc_assert (args != NULL_TREE);
886
887   if (TREE_CODE (* node) != FUNCTION_DECL)
888     {
889       warning (OPT_Wattributes, "%qE attribute only applies to functions",
890                name);
891       * no_add_attrs = true;
892     }
893
894   return NULL_TREE;
895 }
896
897 #undef  TARGET_ATTRIBUTE_TABLE
898 #define TARGET_ATTRIBUTE_TABLE          rl78_attribute_table
899
900 /* Table of RL78-specific attributes.  */
901 const struct attribute_spec rl78_attribute_table[] =
902 {
903   /* Name, min_len, max_len, decl_req, type_req, fn_type_req,
904      affects_type_identity, handler, exclude.  */
905   { "interrupt",      0, -1, true, false, false, false,
906     rl78_handle_func_attribute, NULL },
907   { "brk_interrupt",  0, 0, true, false, false, false,
908     rl78_handle_func_attribute, NULL },
909   { "naked",          0, 0, true, false, false, false,
910     rl78_handle_naked_attribute, NULL },
911   { "saddr",          0, 0, true, false, false, false,
912     rl78_handle_saddr_attribute, NULL },
913   { "vector",         1, -1, true, false, false, false,
914         rl78_handle_vector_attribute, NULL },
915   { NULL,             0, 0, false, false, false, false, NULL, NULL }
916 };
917
918
919 \f
920 /* Break down an address RTX into its component base/index/addend
921    portions and return TRUE if the address is of a valid form, else
922    FALSE.  */
923 static bool
924 characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
925 {
926   *base = NULL_RTX;
927   *index = NULL_RTX;
928   *addend = NULL_RTX;
929
930   if (GET_CODE (x) == UNSPEC
931       && XINT (x, 1) == UNS_ES_ADDR)
932     x = XVECEXP (x, 0, 1);
933
934   if (GET_CODE (x) == REG)
935     {
936       *base = x;
937       return true;
938     }
939
940   /* We sometimes get these without the CONST wrapper */
941   if (GET_CODE (x) == PLUS
942       && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
943       && GET_CODE (XEXP (x, 1)) == CONST_INT)
944     {
945       *addend = x;
946       return true;
947     }
948
949   if (GET_CODE (x) == PLUS)
950     {
951       *base = XEXP (x, 0);
952       x = XEXP (x, 1);
953
954       if (GET_CODE (*base) == SUBREG)
955         {
956           if (GET_MODE (*base) == HImode
957               && GET_MODE (XEXP (*base, 0)) == SImode
958               && GET_CODE (XEXP (*base, 0)) == REG)
959             {
960               /* This is a throw-away rtx just to tell everyone
961                  else what effective register we're using.  */
962               *base = gen_rtx_REG (HImode, REGNO (XEXP (*base, 0)));
963             }
964         }
965
966       if (GET_CODE (*base) != REG
967           && GET_CODE (x) == REG)
968         {
969           rtx tmp = *base;
970           *base = x;
971           x = tmp;
972         }
973
974       if (GET_CODE (*base) != REG)
975         return false;
976
977       if (GET_CODE (x) == ZERO_EXTEND
978           && GET_CODE (XEXP (x, 0)) == REG)
979         {
980           *index = XEXP (x, 0);
981           return false;
982         }
983     }
984
985   switch (GET_CODE (x))
986     {
987     case PLUS:
988       if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
989           && GET_CODE (XEXP (x, 0)) == CONST_INT)
990         {
991           *addend = x;
992           return true;
993         }
994       /* fall through */
995     case MEM:
996     case REG:
997       return false;
998
999     case SUBREG:
1000       switch (GET_CODE (XEXP (x, 0)))
1001         {
1002         case CONST:
1003         case SYMBOL_REF:
1004         case CONST_INT:
1005           *addend = x;
1006           return true;
1007         default:
1008           return false;
1009         }
1010
1011     case CONST:
1012     case SYMBOL_REF:
1013     case CONST_INT:
1014       *addend = x;
1015       return true;
1016
1017     default:
1018       return false;
1019     }
1020
1021   return false;
1022 }
1023
1024 /* Used by the Whb constraint.  Match addresses that use HL+B or HL+C
1025    addressing.  */
1026 bool
1027 rl78_hl_b_c_addr_p (rtx op)
1028 {
1029   rtx hl, bc;
1030
1031   if (GET_CODE (op) != PLUS)
1032     return false;
1033   hl = XEXP (op, 0);
1034   bc = XEXP (op, 1);
1035   if (GET_CODE (hl) == ZERO_EXTEND)
1036     {
1037       rtx tmp = hl;
1038       hl = bc;
1039       bc = tmp;
1040     }
1041   if (GET_CODE (hl) != REG)
1042     return false;
1043   if (GET_CODE (bc) != ZERO_EXTEND)
1044     return false;
1045   bc = XEXP (bc, 0);
1046   if (GET_CODE (bc) != REG)
1047     return false;
1048   if (REGNO (hl) != HL_REG)
1049     return false;
1050   if (REGNO (bc) != B_REG && REGNO (bc) != C_REG)
1051     return false;
1052
1053   return true;
1054 }
1055
1056 #define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
1057
1058 /* Return the appropriate mode for a named address address.  */
1059
1060 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
1061 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
1062
1063 static scalar_int_mode
1064 rl78_addr_space_address_mode (addr_space_t addrspace)
1065 {
1066   switch (addrspace)
1067     {
1068     case ADDR_SPACE_GENERIC:
1069       return HImode;
1070     case ADDR_SPACE_NEAR:
1071       return HImode;
1072     case ADDR_SPACE_FAR:
1073       return SImode;
1074     default:
1075       gcc_unreachable ();
1076     }
1077 }
1078
1079 /* Used in various constraints and predicates to match operands in the
1080    "far" address space.  */
1081 int
1082 rl78_far_p (rtx x)
1083 {
1084   if (! MEM_P (x))
1085     return 0;
1086 #if DEBUG0
1087   fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
1088   fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
1089 #endif
1090
1091   /* Not all far addresses are legitimate, because the devirtualizer
1092      can't handle them.  */
1093   if (! rl78_as_legitimate_address (GET_MODE (x), XEXP (x, 0), false, ADDR_SPACE_FAR))
1094     return 0;
1095
1096   return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) == 32;
1097 }
1098
1099 /* Return the appropriate mode for a named address pointer.  */
1100 #undef  TARGET_ADDR_SPACE_POINTER_MODE
1101 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
1102
1103 static scalar_int_mode
1104 rl78_addr_space_pointer_mode (addr_space_t addrspace)
1105 {
1106   switch (addrspace)
1107     {
1108     case ADDR_SPACE_GENERIC:
1109       return HImode;
1110     case ADDR_SPACE_NEAR:
1111       return HImode;
1112     case ADDR_SPACE_FAR:
1113       return SImode;
1114     default:
1115       gcc_unreachable ();
1116     }
1117 }
1118
1119 /* Returns TRUE for valid addresses.  */
1120 #undef  TARGET_VALID_POINTER_MODE
1121 #define TARGET_VALID_POINTER_MODE rl78_valid_pointer_mode
1122
1123 static bool
1124 rl78_valid_pointer_mode (scalar_int_mode m)
1125 {
1126   return (m == HImode || m == SImode);
1127 }
1128
1129 #undef  TARGET_LEGITIMATE_CONSTANT_P
1130 #define TARGET_LEGITIMATE_CONSTANT_P            rl78_is_legitimate_constant
1131
1132 static bool
1133 rl78_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED)
1134 {
1135   return true;
1136 }
1137
1138 #undef TARGET_LRA_P
1139 #define TARGET_LRA_P hook_bool_void_false
1140
1141 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
1142 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P  rl78_as_legitimate_address
1143
1144 bool
1145 rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
1146                             bool strict ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED)
1147 {
1148   rtx base, index, addend;
1149   bool is_far_addr = false;
1150   int as_bits;
1151
1152   as_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (as));
1153
1154   if (GET_CODE (x) == UNSPEC
1155       && XINT (x, 1) == UNS_ES_ADDR)
1156     {
1157       x = XVECEXP (x, 0, 1);
1158       is_far_addr = true;
1159     }
1160
1161   if (as_bits == 16 && is_far_addr)
1162     return false;
1163
1164   if (! characterize_address (x, &base, &index, &addend))
1165     return false;
1166
1167   /* We can't extract the high/low portions of a PLUS address
1168      involving a register during devirtualization, so make sure all
1169      such __far addresses do not have addends.  This forces GCC to do
1170      the sum separately.  */
1171   if (addend && base && as_bits == 32 && GET_MODE (base) == SImode)
1172     return false;
1173
1174   if (base && index)
1175     {
1176       int ir = REGNO (index);
1177       int br = REGNO (base);
1178
1179 #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
1180       OK (REG_IS (br, HL_REG) && REG_IS (ir, B_REG), "[hl+b]");
1181       OK (REG_IS (br, HL_REG) && REG_IS (ir, C_REG), "[hl+c]");
1182       return false;
1183     }
1184
1185   if (strict && base && GET_CODE (base) == REG && REGNO (base) >= FIRST_PSEUDO_REGISTER)
1186     return false;
1187
1188   if (! cfun->machine->virt_insns_ok && base && GET_CODE (base) == REG
1189       && REGNO (base) >= 8 && REGNO (base) <= 31)
1190     return false;
1191
1192   return true;
1193 }
1194
1195 /* Determine if one named address space is a subset of another.  */
1196 #undef  TARGET_ADDR_SPACE_SUBSET_P
1197 #define TARGET_ADDR_SPACE_SUBSET_P rl78_addr_space_subset_p
1198
1199 static bool
1200 rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
1201 {
1202   int subset_bits;
1203   int superset_bits;
1204
1205   subset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (subset));
1206   superset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (superset));
1207
1208   return (subset_bits <= superset_bits);
1209 }
1210
1211 #undef  TARGET_ADDR_SPACE_CONVERT
1212 #define TARGET_ADDR_SPACE_CONVERT rl78_addr_space_convert
1213
1214 /* Convert from one address space to another.  */
1215 static rtx
1216 rl78_addr_space_convert (rtx op, tree from_type, tree to_type)
1217 {
1218   addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
1219   addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
1220   rtx result;
1221   int to_bits;
1222   int from_bits;
1223
1224   to_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (to_as));
1225   from_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (from_as));
1226
1227   if (to_bits < from_bits)
1228     {
1229       rtx tmp;
1230       /* This is unpredictable, as we're truncating off usable address
1231          bits.  */
1232
1233       warning (OPT_Waddress, "converting far pointer to near pointer");
1234       result = gen_reg_rtx (HImode);
1235       if (GET_CODE (op) == SYMBOL_REF
1236           || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER))
1237         tmp = gen_rtx_raw_SUBREG (HImode, op, 0);
1238       else
1239         tmp = simplify_subreg (HImode, op, SImode, 0);
1240       gcc_assert (tmp != NULL_RTX);
1241       emit_move_insn (result, tmp);
1242       return result;
1243     }
1244   else if (to_bits > from_bits)
1245     {
1246       /* This always works.  */
1247       result = gen_reg_rtx (SImode);
1248       emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op);
1249       if (TREE_CODE (from_type) == POINTER_TYPE
1250           && TREE_CODE (TREE_TYPE (from_type)) == FUNCTION_TYPE)
1251         emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx);
1252       else
1253         emit_move_insn (rl78_subreg (HImode, result, SImode, 2), GEN_INT (0x0f));
1254       return result;
1255     }
1256   else
1257     return op;
1258   gcc_unreachable ();
1259 }
1260
1261 /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P.  */
1262 bool
1263 rl78_regno_mode_code_ok_for_base_p (int regno, machine_mode mode ATTRIBUTE_UNUSED,
1264                                     addr_space_t address_space ATTRIBUTE_UNUSED,
1265                                     int outer_code ATTRIBUTE_UNUSED, int index_code)
1266 {
1267   if (regno <= SP_REG && regno >= 16)
1268     return true;
1269   if (index_code == REG)
1270     return (regno == HL_REG);
1271   if (regno == C_REG || regno == B_REG || regno == E_REG || regno == L_REG)
1272     return true;
1273   return false;
1274 }
1275
1276 /* Implements MODE_CODE_BASE_REG_CLASS.  */
1277 enum reg_class
1278 rl78_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
1279                                addr_space_t address_space ATTRIBUTE_UNUSED,
1280                                int outer_code ATTRIBUTE_UNUSED,
1281                                int index_code ATTRIBUTE_UNUSED)
1282 {
1283   return V_REGS;
1284 }
1285
1286 /* Typical stack layout should looks like this after the function's prologue:
1287
1288                             |    |
1289                               --                       ^
1290                             |    | \                   |
1291                             |    |   arguments saved   | Increasing
1292                             |    |   on the stack      |  addresses
1293     PARENT   arg pointer -> |    | /
1294   -------------------------- ---- -------------------
1295     CHILD                   |ret |   return address
1296                               --
1297                             |    | \
1298                             |    |   call saved
1299                             |    |   registers
1300         frame pointer ->    |    | /
1301                               --
1302                             |    | \
1303                             |    |   local
1304                             |    |   variables
1305                             |    | /
1306                               --
1307                             |    | \
1308                             |    |   outgoing          | Decreasing
1309                             |    |   arguments         |  addresses
1310    current stack pointer -> |    | /                   |
1311   -------------------------- ---- ------------------   V
1312                             |    |                 */
1313
1314 /* Implements INITIAL_ELIMINATION_OFFSET.  The frame layout is
1315    described in the machine_Function struct definition, above.  */
1316 int
1317 rl78_initial_elimination_offset (int from, int to)
1318 {
1319   int rv = 0; /* as if arg to arg */
1320
1321   rl78_compute_frame_info ();
1322
1323   switch (to)
1324     {
1325     case STACK_POINTER_REGNUM:
1326       rv += cfun->machine->framesize_outgoing;
1327       rv += cfun->machine->framesize_locals;
1328       /* Fall through.  */
1329     case FRAME_POINTER_REGNUM:
1330       rv += cfun->machine->framesize_regs;
1331       rv += 4;
1332       break;
1333     default:
1334       gcc_unreachable ();
1335     }
1336
1337   switch (from)
1338     {
1339     case FRAME_POINTER_REGNUM:
1340       rv -= 4;
1341       rv -= cfun->machine->framesize_regs;
1342     case ARG_POINTER_REGNUM:
1343       break;
1344     default:
1345       gcc_unreachable ();
1346     }
1347
1348   return rv;
1349 }
1350
1351 static bool
1352 rl78_is_naked_func (void)
1353 {
1354   return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE);
1355 }
1356
1357 /* Check if the block uses mul/div insns for G13 target.  */
1358
1359 static bool
1360 check_mduc_usage (void)
1361 {
1362   rtx_insn * insn;
1363   basic_block bb;
1364
1365   FOR_EACH_BB_FN (bb, cfun)
1366     {
1367       FOR_BB_INSNS (bb, insn)
1368         {
1369           if (INSN_P (insn)
1370               && (get_attr_is_g13_muldiv_insn (insn) == IS_G13_MULDIV_INSN_YES))
1371             return true;
1372         }
1373     }
1374   return false;
1375 }
1376
1377 /* Expand the function prologue (from the prologue pattern).  */
1378
1379 void
1380 rl78_expand_prologue (void)
1381 {
1382   int i, fs;
1383   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
1384   rtx ax = gen_rtx_REG (HImode, AX_REG);
1385   int rb = 0;
1386
1387   if (rl78_is_naked_func ())
1388     return;
1389
1390   /* Always re-compute the frame info - the register usage may have changed.  */
1391   rl78_compute_frame_info ();
1392
1393   if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
1394     cfun->machine->framesize += ARRAY_SIZE (mduc_regs) * 2;
1395
1396   if (flag_stack_usage_info)
1397     current_function_static_stack_size = cfun->machine->framesize;
1398
1399   if (is_interrupt_func (cfun->decl) && !TARGET_G10)
1400     for (i = 0; i < 4; i++)
1401       if (cfun->machine->need_to_push [i])
1402         {
1403           /* Select Bank 0 if we are using any registers from Bank 0.   */
1404           emit_insn (gen_sel_rb (GEN_INT (0)));
1405           break;
1406         }
1407
1408   for (i = 0; i < 16; i++)
1409     if (cfun->machine->need_to_push [i])
1410       {
1411         int reg = i * 2;
1412
1413         if (TARGET_G10)
1414           {
1415             if (reg >= 8)
1416               {
1417                 emit_move_insn (ax, gen_rtx_REG (HImode, reg));
1418                 reg = AX_REG;
1419               }
1420           }
1421         else
1422           {
1423             int need_bank = i/4;
1424
1425             if (need_bank != rb)
1426               {
1427                 emit_insn (gen_sel_rb (GEN_INT (need_bank)));
1428                 rb = need_bank;
1429               }
1430           }
1431
1432         F (emit_insn (gen_push (gen_rtx_REG (HImode, reg))));
1433       }
1434
1435   if (rb != 0)
1436     emit_insn (gen_sel_rb (GEN_INT (0)));
1437
1438   /* Save ES register inside interrupt functions if it is used.  */
1439   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
1440     {
1441       emit_insn (gen_movqi_from_es (gen_rtx_REG (QImode, A_REG)));
1442       F (emit_insn (gen_push (ax)));
1443     }
1444
1445   /* Save MDUC registers inside interrupt routine.  */
1446   if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
1447     {
1448       for (unsigned i = 0; i < ARRAY_SIZE (mduc_regs); i++)
1449         {
1450           mduc_reg_type *reg = mduc_regs + i;
1451           rtx mem_mduc = gen_rtx_MEM (reg->mode, GEN_INT (reg->address));
1452
1453           MEM_VOLATILE_P (mem_mduc) = 1;
1454           if (reg->mode == QImode)
1455             emit_insn (gen_movqi (gen_rtx_REG (QImode, A_REG), mem_mduc));
1456           else
1457             emit_insn (gen_movhi (gen_rtx_REG (HImode, AX_REG), mem_mduc));
1458
1459           emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG)));
1460         }
1461     }
1462
1463   if (frame_pointer_needed)
1464     {
1465       F (emit_move_insn (ax, sp));
1466       F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), ax));
1467     }
1468
1469   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1470   if (fs > 0)
1471     {
1472       /* If we need to subtract more than 254*3 then it is faster and
1473          smaller to move SP into AX and perform the subtraction there.  */
1474       if (fs > 254 * 3)
1475         {
1476           rtx insn;
1477
1478           emit_move_insn (ax, sp);
1479           emit_insn (gen_subhi3 (ax, ax, GEN_INT (fs)));
1480           insn = F (emit_move_insn (sp, ax));
1481           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1482                         gen_rtx_SET (sp, gen_rtx_PLUS (HImode, sp,
1483                                                        GEN_INT (-fs))));
1484         }
1485       else
1486         {
1487           while (fs > 0)
1488             {
1489               int fs_byte = (fs > 254) ? 254 : fs;
1490
1491               F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte))));
1492               fs -= fs_byte;
1493             }
1494         }
1495     }
1496 }
1497
1498 /* Expand the function epilogue (from the epilogue pattern).  */
1499 void
1500 rl78_expand_epilogue (void)
1501 {
1502   int i, fs;
1503   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
1504   rtx ax = gen_rtx_REG (HImode, AX_REG);
1505   int rb = 0;
1506
1507   if (rl78_is_naked_func ())
1508     return;
1509
1510   if (frame_pointer_needed)
1511     {
1512       emit_move_insn (ax, gen_rtx_REG (HImode, FRAME_POINTER_REGNUM));
1513       emit_move_insn (sp, ax);
1514     }
1515   else
1516     {
1517       fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1518       if (fs > 254 * 3)
1519         {
1520           emit_move_insn (ax, sp);
1521           emit_insn (gen_addhi3 (ax, ax, GEN_INT (fs)));
1522           emit_move_insn (sp, ax);
1523         }
1524       else
1525         {
1526           while (fs > 0)
1527             {
1528               int fs_byte = (fs > 254) ? 254 : fs;
1529
1530               emit_insn (gen_addhi3 (sp, sp, GEN_INT (fs_byte)));
1531               fs -= fs_byte;
1532             }
1533         }
1534     }
1535
1536   /* Restore MDUC registers from interrupt routine.  */
1537   if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
1538     {
1539       for (int i = ARRAY_SIZE (mduc_regs) - 1; i >= 0; i--)
1540         {
1541           mduc_reg_type *reg = mduc_regs + i;
1542           rtx mem_mduc = gen_rtx_MEM (reg->mode, GEN_INT (reg->address));
1543
1544           emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
1545           MEM_VOLATILE_P (mem_mduc) = 1;
1546           if (reg->mode == QImode)
1547             emit_insn (gen_movqi (mem_mduc, gen_rtx_REG (QImode, A_REG)));
1548           else
1549             emit_insn (gen_movhi (mem_mduc, gen_rtx_REG (HImode, AX_REG)));
1550         }
1551     }
1552
1553   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
1554     {
1555       emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
1556       emit_insn (gen_movqi_to_es (gen_rtx_REG (QImode, A_REG)));
1557     }
1558
1559   for (i = 15; i >= 0; i--)
1560     if (cfun->machine->need_to_push [i])
1561       {
1562         rtx dest = gen_rtx_REG (HImode, i * 2);
1563
1564         if (TARGET_G10)
1565           {
1566             if (i < 8)
1567               emit_insn (gen_pop (dest));
1568             else
1569               {
1570                 emit_insn (gen_pop (ax));
1571                 emit_move_insn (dest, ax);
1572                 /* Generate a USE of the pop'd register so that DCE will not eliminate the move.  */
1573                 emit_insn (gen_use (dest));
1574               }
1575           }
1576         else
1577           {
1578             int need_bank = i / 4;
1579
1580             if (need_bank != rb)
1581               {
1582                 emit_insn (gen_sel_rb (GEN_INT (need_bank)));
1583                 rb = need_bank;
1584               }
1585             emit_insn (gen_pop (dest));
1586           }
1587       }
1588
1589   if (rb != 0)
1590     emit_insn (gen_sel_rb (GEN_INT (0)));
1591
1592   if (cfun->machine->trampolines_used)
1593     emit_insn (gen_trampoline_uninit ());
1594
1595   if (is_brk_interrupt_func (cfun->decl))
1596     emit_jump_insn (gen_brk_interrupt_return ());
1597   else if (is_interrupt_func (cfun->decl))
1598     emit_jump_insn (gen_interrupt_return ());
1599   else
1600     emit_jump_insn (gen_rl78_return ());
1601 }
1602
1603 /* Likewise, for exception handlers.  */
1604 void
1605 rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED)
1606 {
1607   /* FIXME - replace this with an indirect jump with stack adjust.  */
1608   emit_jump_insn (gen_rl78_return ());
1609 }
1610
1611 #undef  TARGET_ASM_FUNCTION_PROLOGUE
1612 #define TARGET_ASM_FUNCTION_PROLOGUE    rl78_start_function
1613
1614 static void
1615 add_vector_labels (FILE *file, const char *aname)
1616 {
1617   tree vec_attr;
1618   tree val_attr;
1619   const char *vname = "vect";
1620   const char *s;
1621   int vnum;
1622
1623   /* This node is for the vector/interrupt tag itself */
1624   vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl));
1625   if (!vec_attr)
1626     return;
1627
1628   /* Now point it at the first argument */
1629   vec_attr = TREE_VALUE (vec_attr);
1630
1631   /* Iterate through the arguments.  */
1632   while (vec_attr)
1633     {
1634       val_attr = TREE_VALUE (vec_attr);
1635       switch (TREE_CODE (val_attr))
1636         {
1637         case STRING_CST:
1638           s = TREE_STRING_POINTER (val_attr);
1639           goto string_id_common;
1640
1641         case IDENTIFIER_NODE:
1642           s = IDENTIFIER_POINTER (val_attr);
1643
1644         string_id_common:
1645           if (strcmp (s, "$default") == 0)
1646             {
1647               fprintf (file, "\t.global\t$tableentry$default$%s\n", vname);
1648               fprintf (file, "$tableentry$default$%s:\n", vname);
1649             }
1650           else
1651             vname = s;
1652           break;
1653
1654         case INTEGER_CST:
1655           vnum = TREE_INT_CST_LOW (val_attr);
1656
1657           fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname);
1658           fprintf (file, "$tableentry$%d$%s:\n", vnum, vname);
1659           break;
1660
1661         default:
1662           ;
1663         }
1664
1665       vec_attr = TREE_CHAIN (vec_attr);
1666     }
1667
1668 }
1669
1670 /* We don't use this to actually emit the function prologue.  We use
1671    this to insert a comment in the asm file describing the
1672    function.  */
1673 static void
1674 rl78_start_function (FILE *file)
1675 {
1676   int i;
1677   
1678   add_vector_labels (file, "interrupt");
1679   add_vector_labels (file, "vector");
1680
1681   if (cfun->machine->framesize == 0)
1682     return;
1683   fprintf (file, "\t; start of function\n");
1684
1685   if (cfun->machine->framesize_regs)
1686     {
1687       fprintf (file, "\t; push %d:", cfun->machine->framesize_regs);
1688       for (i = 0; i < 16; i ++)
1689         if (cfun->machine->need_to_push[i])
1690           fprintf (file, " %s", word_regnames[i*2]);
1691       fprintf (file, "\n");
1692     }
1693
1694   if (frame_pointer_needed)
1695     fprintf (file, "\t; $fp points here (r22)\n");
1696
1697   if (cfun->machine->framesize_locals)
1698     fprintf (file, "\t; locals: %d byte%s\n", cfun->machine->framesize_locals,
1699              cfun->machine->framesize_locals == 1 ? "" : "s");
1700
1701   if (cfun->machine->framesize_outgoing)
1702     fprintf (file, "\t; outgoing: %d byte%s\n", cfun->machine->framesize_outgoing,
1703              cfun->machine->framesize_outgoing == 1 ? "" : "s");
1704
1705   if (cfun->machine->uses_es)
1706     fprintf (file, "\t; uses ES register\n");
1707
1708   if (MUST_SAVE_MDUC_REGISTERS)
1709     fprintf (file, "\t; preserves MDUC registers\n");
1710 }
1711
1712 /* Return an RTL describing where a function return value of type RET_TYPE
1713    is held.  */
1714
1715 #undef  TARGET_FUNCTION_VALUE
1716 #define TARGET_FUNCTION_VALUE           rl78_function_value
1717
1718 static rtx
1719 rl78_function_value (const_tree ret_type,
1720                      const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1721                      bool       outgoing ATTRIBUTE_UNUSED)
1722 {
1723   machine_mode mode = TYPE_MODE (ret_type);
1724
1725   return gen_rtx_REG (mode, 8);
1726 }
1727
1728 #undef  TARGET_PROMOTE_FUNCTION_MODE
1729 #define TARGET_PROMOTE_FUNCTION_MODE rl78_promote_function_mode
1730
1731 static machine_mode
1732 rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
1733                             machine_mode mode,
1734                             int *punsignedp ATTRIBUTE_UNUSED,
1735                             const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED)
1736 {
1737   return mode;
1738 }
1739
1740 #undef  TARGET_FUNCTION_ARG
1741 #define TARGET_FUNCTION_ARG             rl78_function_arg
1742
1743 static rtx
1744 rl78_function_arg (cumulative_args_t, const function_arg_info &)
1745 {
1746   return NULL_RTX;
1747 }
1748
1749 #undef  TARGET_FUNCTION_ARG_ADVANCE
1750 #define TARGET_FUNCTION_ARG_ADVANCE     rl78_function_arg_advance
1751
1752 static void
1753 rl78_function_arg_advance (cumulative_args_t cum_v,
1754                            const function_arg_info &arg)
1755 {
1756   int rounded_size;
1757   CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
1758
1759   rounded_size = arg.promoted_size_in_bytes ();
1760   if (rounded_size & 1)
1761     rounded_size ++;
1762   (*cum) += rounded_size;
1763 }
1764
1765 #undef  TARGET_FUNCTION_ARG_BOUNDARY
1766 #define TARGET_FUNCTION_ARG_BOUNDARY rl78_function_arg_boundary
1767
1768 static unsigned int
1769 rl78_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
1770                             const_tree type ATTRIBUTE_UNUSED)
1771 {
1772   return 16;
1773 }
1774
1775 /* Supported modifier letters:
1776
1777    A - address of a MEM
1778    S - SADDR form of a real register
1779    v - real register corresponding to a virtual register
1780    m - minus - negative of CONST_INT value.
1781    C - inverse of a conditional (NE vs EQ for example)
1782    C - complement of an integer
1783    z - collapsed conditional
1784    s - shift count mod 8
1785    S - shift count mod 16
1786    r - reverse shift count (8-(count mod 8))
1787    B - bit position
1788
1789    h - bottom HI of an SI
1790    H - top HI of an SI
1791    q - bottom QI of an HI
1792    Q - top QI of an HI
1793    e - third QI of an SI (i.e. where the ES register gets values from)
1794    E - fourth QI of an SI (i.e. MSB)
1795
1796    p - Add +0 to a zero-indexed HL based address.
1797 */
1798
1799 /* Implements the bulk of rl78_print_operand, below.  We do it this
1800    way because we need to test for a constant at the top level and
1801    insert the '#', but not test for it anywhere else as we recurse
1802    down into the operand.  */
1803 static void
1804 rl78_print_operand_1 (FILE * file, rtx op, int letter)
1805 {
1806   int need_paren;
1807
1808   switch (GET_CODE (op))
1809     {
1810     case MEM:
1811       if (letter == 'A')
1812         rl78_print_operand_1 (file, XEXP (op, 0), letter);
1813       else
1814         {
1815           if (rl78_far_p (op))
1816             {
1817               fprintf (file, "es:");
1818               if (GET_CODE (XEXP (op, 0)) == UNSPEC)
1819                 op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1));
1820             }
1821           if (letter == 'H')
1822             {
1823               op = adjust_address (op, HImode, 2);
1824               letter = 0;
1825             }
1826           if (letter == 'h')
1827             {
1828               op = adjust_address (op, HImode, 0);
1829               letter = 0;
1830             }
1831           if (letter == 'Q')
1832             {
1833               op = adjust_address (op, QImode, 1);
1834               letter = 0;
1835             }
1836           if (letter == 'q')
1837             {
1838               op = adjust_address (op, QImode, 0);
1839               letter = 0;
1840             }
1841           if (letter == 'e')
1842             {
1843               op = adjust_address (op, QImode, 2);
1844               letter = 0;
1845             }
1846           if (letter == 'E')
1847             {
1848               op = adjust_address (op, QImode, 3);
1849               letter = 0;
1850             }
1851           if (CONSTANT_P (XEXP (op, 0)))
1852             {
1853               if (!rl78_saddr_p (op))
1854                 fprintf (file, "!");
1855               rl78_print_operand_1 (file, XEXP (op, 0), letter);
1856             }
1857           else if (GET_CODE (XEXP (op, 0)) == PLUS
1858                    && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF)
1859             {
1860               if (!rl78_saddr_p (op))
1861                 fprintf (file, "!");
1862               rl78_print_operand_1 (file, XEXP (op, 0), letter);
1863             }
1864           else if (GET_CODE (XEXP (op, 0)) == PLUS
1865                    && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
1866                    && REGNO (XEXP (XEXP (op, 0), 0)) == 2)
1867             {
1868               rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u');
1869               fprintf (file, "[");
1870               rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0);
1871               if (letter == 'p' && GET_CODE (XEXP (op, 0)) == REG)
1872                 fprintf (file, "+0");
1873               fprintf (file, "]");
1874             }
1875           else
1876             {
1877               op = XEXP (op, 0);
1878               fprintf (file, "[");
1879               rl78_print_operand_1 (file, op, letter);
1880               if (letter == 'p' && REG_P (op) && REGNO (op) == 6)
1881                 fprintf (file, "+0");
1882               fprintf (file, "]");
1883             }
1884         }
1885       break;
1886
1887     case REG:
1888       if (letter == 'Q')
1889         fprintf (file, "%s", reg_names [REGNO (op) | 1]);
1890       else if (letter == 'H')
1891         fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1892       else if (letter == 'q')
1893         fprintf (file, "%s", reg_names [REGNO (op) & ~1]);
1894       else if (letter == 'e')
1895         fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1896       else if (letter == 'E')
1897         fprintf (file, "%s", reg_names [REGNO (op) + 3]);
1898       else if (letter == 'S')
1899         fprintf (file, "0x%x", 0xffef8 + REGNO (op));
1900       else if (GET_MODE (op) == HImode
1901                && ! (REGNO (op) & ~0xfe))
1902         {
1903           if (letter == 'v')
1904             fprintf (file, "%s", word_regnames [REGNO (op) % 8]);
1905           else
1906             fprintf (file, "%s", word_regnames [REGNO (op)]);
1907         }
1908       else
1909         fprintf (file, "%s", reg_names [REGNO (op)]);
1910       break;
1911
1912     case CONST_INT:
1913       if (letter == 'Q')
1914         fprintf (file, "%ld", INTVAL (op) >> 8);
1915       else if (letter == 'H')
1916         fprintf (file, "%ld", INTVAL (op) >> 16);
1917       else if (letter == 'q')
1918         fprintf (file, "%ld", INTVAL (op) & 0xff);
1919       else if (letter == 'h')
1920         fprintf (file, "%ld", INTVAL (op) & 0xffff);
1921       else if (letter == 'e')
1922         fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
1923       else if (letter == 'B')
1924         {
1925           int ival = INTVAL (op);
1926           if (ival == -128)
1927             ival = 0x80;
1928           if (exact_log2 (ival) >= 0)
1929             fprintf (file, "%d", exact_log2 (ival));
1930           else
1931             fprintf (file, "%d", exact_log2 (~ival & 0xff));
1932         }
1933       else if (letter == 'E')
1934         fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff);
1935       else if (letter == 'm')
1936         fprintf (file, "%ld", - INTVAL (op));
1937       else if (letter == 's')
1938         fprintf (file, "%ld", INTVAL (op) % 8);
1939       else if (letter == 'S')
1940         fprintf (file, "%ld", INTVAL (op) % 16);
1941       else if (letter == 'r')
1942         fprintf (file, "%ld", 8 - (INTVAL (op) % 8));
1943       else if (letter == 'C')
1944         fprintf (file, "%ld", (INTVAL (op) ^ 0x8000) & 0xffff);
1945       else
1946         fprintf (file, "%ld", INTVAL (op));
1947       break;
1948
1949     case CONST:
1950       rl78_print_operand_1 (file, XEXP (op, 0), letter);
1951       break;
1952
1953     case ZERO_EXTRACT:
1954       {
1955         int bits = INTVAL (XEXP (op, 1));
1956         int ofs = INTVAL (XEXP (op, 2));
1957         if (bits == 16 && ofs == 0)
1958           fprintf (file, "%%lo16(");
1959         else if (bits == 16 && ofs == 16)
1960           fprintf (file, "%%hi16(");
1961         else if (bits == 8 && ofs == 16)
1962           fprintf (file, "%%hi8(");
1963         else
1964           gcc_unreachable ();
1965         rl78_print_operand_1 (file, XEXP (op, 0), 0);
1966         fprintf (file, ")");
1967       }
1968       break;
1969
1970     case ZERO_EXTEND:
1971       if (GET_CODE (XEXP (op, 0)) == REG)
1972         fprintf (file, "%s", reg_names [REGNO (XEXP (op, 0))]);
1973       else
1974         print_rtl (file, op);
1975       break;
1976
1977     case PLUS:
1978       need_paren = 0;
1979       if (letter == 'H')
1980         {
1981           fprintf (file, "%%hi16(");
1982           need_paren = 1;
1983           letter = 0;
1984         }
1985       if (letter == 'h')
1986         {
1987           fprintf (file, "%%lo16(");
1988           need_paren = 1;
1989           letter = 0;
1990         }
1991       if (letter == 'e')
1992         {
1993           fprintf (file, "%%hi8(");
1994           need_paren = 1;
1995           letter = 0;
1996         }
1997       if (letter == 'q' || letter == 'Q')
1998         output_operand_lossage ("q/Q modifiers invalid for symbol references");
1999
2000       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
2001         {
2002           if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
2003               && SYMBOL_REF_DECL (XEXP (op, 1))
2004               && TREE_CODE (SYMBOL_REF_DECL (XEXP (op, 1))) == FUNCTION_DECL)
2005             {
2006               fprintf (file, "%%code(");
2007               assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (XEXP (op, 1), 0)));
2008               fprintf (file, "+");
2009               rl78_print_operand_1 (file, XEXP (op, 0), letter);
2010               fprintf (file, ")");
2011             }
2012           else
2013             {
2014               rl78_print_operand_1 (file, XEXP (op, 1), letter);
2015               fprintf (file, "+");
2016               rl78_print_operand_1 (file, XEXP (op, 0), letter);
2017             }
2018         }
2019       else
2020         {
2021           if (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
2022               && SYMBOL_REF_DECL (XEXP (op, 0))
2023               && TREE_CODE (SYMBOL_REF_DECL (XEXP (op, 0))) == FUNCTION_DECL)
2024             {
2025               fprintf (file, "%%code(");
2026               assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (XEXP (op, 0), 0)));
2027               fprintf (file, "+");
2028               rl78_print_operand_1 (file, XEXP (op, 1), letter);
2029               fprintf (file, ")");
2030             }
2031           else
2032             {
2033               rl78_print_operand_1 (file, XEXP (op, 0), letter);
2034               fprintf (file, "+");
2035               rl78_print_operand_1 (file, XEXP (op, 1), letter);
2036             }
2037         }
2038       if (need_paren)
2039         fprintf (file, ")");
2040       break;
2041
2042     case SUBREG:
2043       if (GET_MODE (op) == HImode
2044           && SUBREG_BYTE (op) == 0)
2045         {
2046           fprintf (file, "%%lo16(");
2047           rl78_print_operand_1 (file, SUBREG_REG (op), 0);
2048           fprintf (file, ")");
2049         }
2050       else if (GET_MODE (op) == HImode
2051                && SUBREG_BYTE (op) == 2)
2052         {
2053           fprintf (file, "%%hi16(");
2054           rl78_print_operand_1 (file, SUBREG_REG (op), 0);
2055           fprintf (file, ")");
2056         }
2057       else
2058         {
2059           fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
2060         }
2061       break;
2062
2063     case SYMBOL_REF:
2064       need_paren = 0;
2065       if (letter == 'H')
2066         {
2067           fprintf (file, "%%hi16(");
2068           need_paren = 1;
2069           letter = 0;
2070         }
2071       if (letter == 'h')
2072         {
2073           fprintf (file, "%%lo16(");
2074           need_paren = 1;
2075           letter = 0;
2076         }
2077       if (letter == 'e')
2078         {
2079           fprintf (file, "%%hi8(");
2080           need_paren = 1;
2081           letter = 0;
2082         }
2083       if (letter == 'q' || letter == 'Q')
2084         output_operand_lossage ("q/Q modifiers invalid for symbol references");
2085
2086       if (SYMBOL_REF_DECL (op) && TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL)
2087         {
2088           fprintf (file, "%%code(");
2089           assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
2090           fprintf (file, ")");
2091         }
2092       else
2093         assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
2094       if (need_paren)
2095         fprintf (file, ")");
2096       break;
2097
2098     case CODE_LABEL:
2099     case LABEL_REF:
2100       output_asm_label (op);
2101       break;
2102
2103     case LTU:
2104       if (letter == 'z')
2105         fprintf (file, "#comparison eliminated");
2106       else
2107         fprintf (file, letter == 'C' ? "nc" : "c");
2108       break;
2109     case LEU:
2110       if (letter == 'z')
2111         fprintf (file, "br");
2112       else
2113         fprintf (file, letter == 'C' ? "h" : "nh");
2114       break;
2115     case GEU:
2116       if (letter == 'z')
2117         fprintf (file, "br");
2118       else
2119         fprintf (file, letter == 'C' ? "c" : "nc");
2120       break;
2121     case GTU:
2122       if (letter == 'z')
2123         fprintf (file, "#comparison eliminated");
2124       else
2125         fprintf (file, letter == 'C' ? "nh" : "h");
2126       break;
2127     case EQ:
2128       if (letter == 'z')
2129         fprintf (file, "br");
2130       else
2131         fprintf (file, letter == 'C' ? "nz" : "z");
2132       break;
2133     case NE:
2134       if (letter == 'z')
2135         fprintf (file, "#comparison eliminated");
2136       else
2137         fprintf (file, letter == 'C' ? "z" : "nz");
2138       break;
2139
2140     /* Note: these assume appropriate adjustments were made so that
2141        unsigned comparisons, which is all this chip has, will
2142        work.  */
2143     case LT:
2144       if (letter == 'z')
2145         fprintf (file, "#comparison eliminated");
2146       else
2147         fprintf (file, letter == 'C' ? "nc" : "c");
2148       break;
2149     case LE:
2150       if (letter == 'z')
2151         fprintf (file, "br");
2152       else
2153         fprintf (file, letter == 'C' ? "h" : "nh");
2154       break;
2155     case GE:
2156       if (letter == 'z')
2157         fprintf (file, "br");
2158       else
2159         fprintf (file, letter == 'C' ? "c" : "nc");
2160       break;
2161     case GT:
2162       if (letter == 'z')
2163         fprintf (file, "#comparison eliminated");
2164       else
2165         fprintf (file, letter == 'C' ? "nh" : "h");
2166       break;
2167
2168     default:
2169       fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
2170       break;
2171     }
2172 }
2173
2174 #undef  TARGET_PRINT_OPERAND
2175 #define TARGET_PRINT_OPERAND            rl78_print_operand
2176
2177 static void
2178 rl78_print_operand (FILE * file, rtx op, int letter)
2179 {
2180   if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B')
2181     fprintf (file, "#");
2182   rl78_print_operand_1 (file, op, letter);
2183 }
2184
2185 #undef  TARGET_TRAMPOLINE_INIT
2186 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
2187
2188 /* Note that the RL78's addressing makes it very difficult to do
2189    trampolines on the stack.  So, libgcc has a small pool of
2190    trampolines from which one is allocated to this task.  */
2191 static void
2192 rl78_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
2193 {
2194   rtx mov_addr, thunk_addr;
2195   rtx function = XEXP (DECL_RTL (fndecl), 0);
2196
2197   mov_addr = adjust_address (m_tramp, HImode, 0);
2198   thunk_addr = gen_reg_rtx (HImode);
2199
2200   function = force_reg (HImode, function);
2201   static_chain = force_reg (HImode, static_chain);
2202
2203   emit_insn (gen_trampoline_init (thunk_addr, function, static_chain));
2204   emit_move_insn (mov_addr, thunk_addr);
2205
2206   cfun->machine->trampolines_used = 1;
2207 }
2208
2209 #undef  TARGET_TRAMPOLINE_ADJUST_ADDRESS
2210 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS rl78_trampoline_adjust_address
2211
2212 static rtx
2213 rl78_trampoline_adjust_address (rtx m_tramp)
2214 {
2215   rtx x = gen_rtx_MEM (HImode, m_tramp);
2216   return x;
2217 }
2218 \f
2219 /* Expander for cbranchqi4 and cbranchhi4.  RL78 is missing some of
2220    the "normal" compares, specifically, it only has unsigned compares,
2221    so we must synthesize the missing ones.  */
2222 void
2223 rl78_expand_compare (rtx *operands)
2224 {
2225   if (GET_CODE (operands[2]) == MEM)
2226     operands[2] = copy_to_mode_reg (GET_MODE (operands[2]), operands[2]);
2227 }
2228
2229 \f
2230
2231 /* Define this to 1 if you are debugging the peephole optimizers.  */
2232 #define DEBUG_PEEP 0
2233
2234 /* Predicate used to enable the peephole2 patterns in rl78-virt.md.
2235    The default "word" size is a byte so we can effectively use all the
2236    registers, but we want to do 16-bit moves whenever possible.  This
2237    function determines when such a move is an option.  */
2238 bool
2239 rl78_peep_movhi_p (rtx *operands)
2240 {
2241   int i;
2242   rtx m, a;
2243
2244   /* (set (op0) (op1))
2245      (set (op2) (op3)) */
2246
2247   if (! rl78_virt_insns_ok ())
2248     return false;
2249
2250 #if DEBUG_PEEP
2251   fprintf (stderr, "\033[33m");
2252   debug_rtx (operands[0]);
2253   debug_rtx (operands[1]);
2254   debug_rtx (operands[2]);
2255   debug_rtx (operands[3]);
2256   fprintf (stderr, "\033[0m");
2257 #endif
2258
2259   /* You can move a constant to memory as QImode, but not HImode.  */
2260   if (GET_CODE (operands[0]) == MEM
2261       && GET_CODE (operands[1]) != REG)
2262     {
2263 #if DEBUG_PEEP
2264       fprintf (stderr, "no peep: move constant to memory\n");
2265 #endif
2266       return false;
2267     }
2268
2269   if (rtx_equal_p (operands[0], operands[3]))
2270     {
2271 #if DEBUG_PEEP
2272       fprintf (stderr, "no peep: overlapping\n");
2273 #endif
2274       return false;
2275     }
2276
2277   for (i = 0; i < 2; i ++)
2278     {
2279       if (GET_CODE (operands[i]) != GET_CODE (operands[i+2]))
2280         {
2281 #if DEBUG_PEEP
2282           fprintf (stderr, "no peep: different codes\n");
2283 #endif
2284           return false;
2285         }
2286       if (GET_MODE (operands[i]) != GET_MODE (operands[i+2]))
2287         {
2288 #if DEBUG_PEEP
2289           fprintf (stderr, "no peep: different modes\n");
2290 #endif
2291           return false;
2292         }
2293
2294       switch (GET_CODE (operands[i]))
2295         {
2296         case REG:
2297           /*   LSB                      MSB  */
2298           if (REGNO (operands[i]) + 1 != REGNO (operands[i+2])
2299               || GET_MODE (operands[i]) != QImode)
2300             {
2301 #if DEBUG_PEEP
2302               fprintf (stderr, "no peep: wrong regnos %d %d %d\n",
2303                        REGNO (operands[i]), REGNO (operands[i+2]),
2304                        i);
2305 #endif
2306               return false;
2307             }
2308           if (! rl78_hard_regno_mode_ok (REGNO (operands[i]), HImode))
2309             {
2310 #if DEBUG_PEEP
2311               fprintf (stderr, "no peep: reg %d not HI\n", REGNO (operands[i]));
2312 #endif
2313               return false;
2314             }
2315           break;
2316
2317         case CONST_INT:
2318           break;
2319
2320         case MEM:
2321           if (GET_MODE (operands[i]) != QImode)
2322             return false;
2323           if (MEM_ALIGN (operands[i]) < 16)
2324             return false;
2325           a = XEXP (operands[i], 0);
2326           if (GET_CODE (a) == CONST)
2327             a = XEXP (a, 0);
2328           if (GET_CODE (a) == PLUS)
2329             a = XEXP (a, 1);
2330           if (GET_CODE (a) == CONST_INT
2331               && INTVAL (a) & 1)
2332             {
2333 #if DEBUG_PEEP
2334               fprintf (stderr, "no peep: misaligned mem %d\n", i);
2335               debug_rtx (operands[i]);
2336 #endif
2337               return false;
2338             }
2339           m = adjust_address (operands[i], QImode, 1);
2340           if (! rtx_equal_p (m, operands[i+2]))
2341             {
2342 #if DEBUG_PEEP
2343               fprintf (stderr, "no peep: wrong mem %d\n", i);
2344               debug_rtx (m);
2345               debug_rtx (operands[i+2]);
2346 #endif
2347               return false;
2348             }
2349           break;
2350
2351         default:
2352 #if DEBUG_PEEP
2353           fprintf (stderr, "no peep: wrong rtx %d\n", i);
2354 #endif
2355           return false;
2356         }
2357     }
2358 #if DEBUG_PEEP
2359   fprintf (stderr, "\033[32mpeep!\033[0m\n");
2360 #endif
2361   return true;
2362 }
2363
2364 /* Likewise, when a peephole is activated, this function helps compute
2365    the new operands.  */
2366 void
2367 rl78_setup_peep_movhi (rtx *operands)
2368 {
2369   int i;
2370
2371   for (i = 0; i < 2; i ++)
2372     {
2373       switch (GET_CODE (operands[i]))
2374         {
2375         case REG:
2376           operands[i+4] = gen_rtx_REG (HImode, REGNO (operands[i]));
2377           break;
2378
2379         case CONST_INT:
2380           operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char) INTVAL (operands[i+2])) * 256);
2381           break;
2382
2383         case MEM:
2384           operands[i+4] = adjust_address (operands[i], HImode, 0);
2385           break;
2386
2387         default:
2388           break;
2389         }
2390     }
2391 }
2392 \f
2393 /*
2394         How Devirtualization works in the RL78 GCC port
2395
2396 Background
2397
2398 The RL78 is an 8-bit port with some 16-bit operations.  It has 32
2399 bytes of register space, in four banks, memory-mapped.  One bank is
2400 the "selected" bank and holds the registers used for primary
2401 operations.  Since the registers are memory mapped, often you can
2402 still refer to the unselected banks via memory accesses.
2403
2404 Virtual Registers
2405
2406 The GCC port uses bank 0 as the "selected" registers (A, X, BC, etc)
2407 and refers to the other banks via their memory addresses, although
2408 they're treated as regular registers internally.  These "virtual"
2409 registers are R8 through R23 (bank3 is reserved for asm-based
2410 interrupt handlers).
2411
2412 There are four machine description files:
2413
2414 rl78.md        - common register-independent patterns and definitions
2415 rl78-expand.md - expanders
2416 rl78-virt.md   - patterns that match BEFORE devirtualization
2417 rl78-real.md   - patterns that match AFTER devirtualization
2418
2419 At least through register allocation and reload, gcc is told that it
2420 can do pretty much anything - but may only use the virtual registers.
2421 GCC cannot properly create the varying addressing modes that the RL78
2422 supports in an efficient way.
2423
2424 Sometime after reload, the RL78 backend "devirtualizes" the RTL.  It
2425 uses the "valloc" attribute in rl78-virt.md for determining the rules
2426 by which it will replace virtual registers with real registers (or
2427 not) and how to make up addressing modes.  For example, insns tagged
2428 with "ro1" have a single read-only parameter, which may need to be
2429 moved from memory/constant/vreg to a suitable real register.  As part
2430 of devirtualization, a flag is toggled, disabling the rl78-virt.md
2431 patterns and enabling the rl78-real.md patterns.  The new patterns'
2432 constraints are used to determine the real registers used.  NOTE:
2433 patterns in rl78-virt.md essentially ignore the constrains and rely on
2434 predicates, where the rl78-real.md ones essentially ignore the
2435 predicates and rely on the constraints.
2436
2437 The devirtualization pass is scheduled via the pass manager (despite
2438 being called "rl78_reorg") so it can be scheduled prior to var-track
2439 (the idea is to let gdb know about the new registers).  Ideally, it
2440 would be scheduled right after pro/epilogue generation, so the
2441 post-reload optimizers could operate on the real registers, but when I
2442 tried that there were some issues building the target libraries.
2443
2444 During devirtualization, a simple register move optimizer is run.  It
2445 would be better to run a full CSE/propogation pass on it though, but
2446 that has not yet been attempted.
2447
2448  */
2449 #define DEBUG_ALLOC 0
2450
2451 #define OP(x) (*recog_data.operand_loc[x])
2452
2453 /* This array is used to hold knowledge about the contents of the
2454    real registers (A ... H), the memory-based registers (r8 ... r31)
2455    and the first NUM_STACK_LOCS words on the stack.  We use this to
2456    avoid generating redundant move instructions.
2457
2458    A value in the range 0 .. 31 indicates register A .. r31.
2459    A value in the range 32 .. 63 indicates stack slot (value - 32).
2460    A value of NOT_KNOWN indicates that the contents of that location
2461    are not known.  */
2462
2463 #define NUM_STACK_LOCS  32
2464 #define NOT_KNOWN       127
2465
2466 static unsigned char content_memory [32 + NUM_STACK_LOCS];
2467
2468 static unsigned char saved_update_index = NOT_KNOWN;
2469 static unsigned char saved_update_value;
2470 static machine_mode saved_update_mode;
2471
2472
2473 static inline void
2474 clear_content_memory (void)
2475 {
2476   memset (content_memory, NOT_KNOWN, sizeof content_memory);
2477   if (dump_file)
2478     fprintf (dump_file, "  clear content memory\n");
2479   saved_update_index = NOT_KNOWN;
2480 }
2481
2482 /* Convert LOC into an index into the content_memory array.
2483    If LOC cannot be converted, return NOT_KNOWN.  */
2484
2485 static unsigned char
2486 get_content_index (rtx loc)
2487 {
2488   machine_mode mode;
2489
2490   if (loc == NULL_RTX)
2491     return NOT_KNOWN;
2492
2493   if (REG_P (loc))
2494     {
2495       if (REGNO (loc) < 32)
2496         return REGNO (loc);
2497       return NOT_KNOWN;
2498     }
2499
2500   mode = GET_MODE (loc);
2501
2502   if (! rl78_stack_based_mem (loc, mode))
2503     return NOT_KNOWN;
2504
2505   loc = XEXP (loc, 0);
2506
2507   if (REG_P (loc))
2508     /* loc = MEM (SP) */
2509     return 32;
2510
2511   /* loc = MEM (PLUS (SP, INT)).  */
2512   loc = XEXP (loc, 1);
2513
2514   if (INTVAL (loc) < NUM_STACK_LOCS)
2515     return 32 + INTVAL (loc);
2516
2517   return NOT_KNOWN;
2518 }
2519
2520 /* Return a string describing content INDEX in mode MODE.
2521    WARNING: Can return a pointer to a static buffer.  */
2522 static const char *
2523 get_content_name (unsigned char index, machine_mode mode)
2524 {
2525   static char buffer [128];
2526
2527   if (index == NOT_KNOWN)
2528     return "Unknown";
2529
2530   if (index > 31)
2531     sprintf (buffer, "stack slot %d", index - 32);
2532   else if (mode == HImode)
2533     sprintf (buffer, "%s%s",
2534              reg_names [index + 1], reg_names [index]);
2535   else
2536     return reg_names [index];
2537
2538   return buffer;
2539 }
2540
2541 #if DEBUG_ALLOC
2542
2543 static void
2544 display_content_memory (FILE * file)
2545 {
2546   unsigned int i;
2547
2548   fprintf (file, " Known memory contents:\n");
2549
2550   for (i = 0; i < sizeof content_memory; i++)
2551     if (content_memory[i] != NOT_KNOWN)
2552       {
2553         fprintf (file, "   %s contains a copy of ", get_content_name (i, QImode));
2554         fprintf (file, "%s\n", get_content_name (content_memory [i], QImode));
2555       }
2556 }
2557 #endif
2558
2559 static void
2560 update_content (unsigned char index, unsigned char val, machine_mode mode)
2561 {
2562   unsigned int i;
2563
2564   gcc_assert (index < sizeof content_memory);
2565
2566   content_memory [index] = val;
2567   if (val != NOT_KNOWN)
2568     content_memory [val] = index;
2569
2570   /* Make the entry in dump_file *before* VAL is increased below.  */
2571   if (dump_file)
2572     {
2573       fprintf (dump_file, "  %s now contains ", get_content_name (index, mode));
2574       if (val == NOT_KNOWN)
2575         fprintf (dump_file, "Unknown\n");
2576       else
2577         fprintf (dump_file, "%s and vice versa\n", get_content_name (val, mode));
2578     }
2579
2580   if (mode == HImode)
2581     {
2582       val = val == NOT_KNOWN ? val : val + 1;
2583
2584       content_memory [index + 1] = val;
2585       if (val != NOT_KNOWN)
2586         {
2587           content_memory [val] = index + 1;
2588           -- val;
2589         }
2590     }
2591
2592   /* Any other places that had INDEX recorded as their contents are now invalid.  */
2593   for (i = 0; i < sizeof content_memory; i++)
2594     {
2595       if (i == index
2596           || (val != NOT_KNOWN && i == val))
2597         {
2598           if (mode == HImode)
2599             ++ i;
2600           continue;
2601         }
2602
2603       if (content_memory[i] == index
2604           || (val != NOT_KNOWN && content_memory[i] == val))
2605         {
2606           content_memory[i] = NOT_KNOWN;
2607
2608           if (dump_file)
2609             fprintf (dump_file, "  %s cleared\n", get_content_name (i, mode));
2610
2611           if (mode == HImode)
2612             content_memory[++ i] = NOT_KNOWN;
2613         }
2614     }
2615 }
2616
2617 /* Record that LOC contains VALUE.
2618    For HImode locations record that LOC+1 contains VALUE+1.
2619    If LOC is not a register or stack slot, do nothing.
2620    If VALUE is not a register or stack slot, clear the recorded content.  */
2621
2622 static void
2623 record_content (rtx loc, rtx value)
2624 {
2625   machine_mode mode;
2626   unsigned char index;
2627   unsigned char val;
2628
2629   if ((index = get_content_index (loc)) == NOT_KNOWN)
2630     return;
2631
2632   val = get_content_index (value);
2633
2634   mode = GET_MODE (loc);
2635
2636   if (val == index)
2637     {
2638       if (! optimize)
2639         return;
2640
2641       /* This should not happen when optimizing.  */
2642 #if 1
2643       fprintf (stderr, "ASSIGNMENT of location to itself detected! [%s]\n",
2644                get_content_name (val, mode));
2645       return;
2646 #else
2647       gcc_unreachable ();
2648 #endif
2649     }
2650
2651   update_content (index, val, mode);
2652 }
2653
2654 /* Returns TRUE if LOC already contains a copy of VALUE.  */
2655
2656 static bool
2657 already_contains (rtx loc, rtx value)
2658 {
2659   unsigned char index;
2660   unsigned char val;
2661
2662   if ((index = get_content_index (loc)) == NOT_KNOWN)
2663     return false;
2664
2665   if ((val = get_content_index (value)) == NOT_KNOWN)
2666     return false;
2667
2668   if (content_memory [index] != val)
2669     return false;
2670
2671   if (GET_MODE (loc) == HImode)
2672     return content_memory [index + 1] == val + 1;
2673
2674   return true;
2675 }
2676
2677 bool
2678 rl78_es_addr (rtx addr)
2679 {
2680   if (GET_CODE (addr) == MEM)
2681     addr = XEXP (addr, 0);
2682   if (GET_CODE (addr) != UNSPEC)
2683     return false;
2684   if (XINT (addr, 1) != UNS_ES_ADDR)
2685     return false;
2686   return true;
2687 }
2688
2689 rtx
2690 rl78_es_base (rtx addr)
2691 {
2692   if (GET_CODE (addr) == MEM)
2693     addr = XEXP (addr, 0);
2694   addr = XVECEXP (addr, 0, 1);
2695   if (GET_CODE (addr) == CONST
2696       && GET_CODE (XEXP (addr, 0)) == ZERO_EXTRACT)
2697     addr = XEXP (XEXP (addr, 0), 0);
2698   /* Mode doesn't matter here.  */
2699   return gen_rtx_MEM (HImode, addr);
2700 }
2701
2702 /* Rescans an insn to see if it's recognized again.  This is done
2703    carefully to ensure that all the constraint information is accurate
2704    for the newly matched insn.  */
2705 static bool
2706 insn_ok_now (rtx_insn * insn)
2707 {
2708   rtx pattern = PATTERN (insn);
2709   int i;
2710
2711   INSN_CODE (insn) = -1;
2712
2713   if (recog (pattern, insn, 0) > -1)
2714     {
2715       extract_insn (insn);
2716       if (constrain_operands (1, get_preferred_alternatives (insn)))
2717         {
2718 #if DEBUG_ALLOC
2719           fprintf (stderr, "\033[32m");
2720           debug_rtx (insn);
2721           fprintf (stderr, "\033[0m");
2722 #endif
2723           if (SET_P (pattern))
2724             record_content (SET_DEST (pattern), SET_SRC (pattern));
2725
2726           /* We need to detect far addresses that haven't been
2727              converted to es/lo16 format.  */
2728           for (i=0; i<recog_data.n_operands; i++)
2729             if (GET_CODE (OP (i)) == MEM
2730                 && GET_MODE (XEXP (OP (i), 0)) == SImode
2731                 && GET_CODE (XEXP (OP (i), 0)) != UNSPEC)
2732               goto not_ok;
2733
2734           return true;
2735         }
2736     }
2737
2738   /* INSN is not OK as-is.  It may not be recognized in real mode or
2739      it might not have satisfied its constraints in real mode.  Either
2740      way it will require fixups.
2741
2742      It is vital we always re-recognize at this point as some insns
2743      have fewer operands in real mode than virtual mode.  If we do
2744      not re-recognize, then the recog_data will refer to real mode
2745      operands and we may read invalid data.  Usually this isn't a
2746      problem, but once in a while the data we read is bogus enough
2747      to cause a segfault or other undesirable behavior.  */
2748  not_ok:
2749
2750   /* We need to re-recog the insn with virtual registers to get
2751      the operands.  */
2752     INSN_CODE (insn) = -1;
2753     cfun->machine->virt_insns_ok = 1;
2754     if (recog (pattern, insn, 0) > -1)
2755       {
2756         extract_insn (insn);
2757         /* In theory this should always be true.  */
2758         if (constrain_operands (0, get_preferred_alternatives (insn)))
2759           {
2760             cfun->machine->virt_insns_ok = 0;
2761             return false;
2762           }
2763       }
2764
2765 #if DEBUG_ALLOC
2766   fprintf (stderr, "\033[41;30m Unrecognized *virtual* insn \033[0m\n");
2767   debug_rtx (insn);
2768 #endif
2769   gcc_unreachable ();
2770   return false;
2771 }
2772
2773 #if DEBUG_ALLOC
2774 #define WORKED      fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__)
2775 #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__)
2776 #define FAILED      fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable ()
2777 #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; }
2778 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } FAILED
2779 #else
2780 #define FAILED gcc_unreachable ()
2781 #define MAYBE_OK(insn) if (insn_ok_now (insn)) return;
2782 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) return; FAILED
2783 #endif
2784
2785 /* Registers into which we move the contents of virtual registers.  */
2786 #define X gen_rtx_REG (QImode, X_REG)
2787 #define A gen_rtx_REG (QImode, A_REG)
2788 #define C gen_rtx_REG (QImode, C_REG)
2789 #define B gen_rtx_REG (QImode, B_REG)
2790 #define E gen_rtx_REG (QImode, E_REG)
2791 #define D gen_rtx_REG (QImode, D_REG)
2792 #define L gen_rtx_REG (QImode, L_REG)
2793 #define H gen_rtx_REG (QImode, H_REG)
2794
2795 #define AX gen_rtx_REG (HImode, AX_REG)
2796 #define BC gen_rtx_REG (HImode, BC_REG)
2797 #define DE gen_rtx_REG (HImode, DE_REG)
2798 #define HL gen_rtx_REG (HImode, HL_REG)
2799
2800 /* Returns TRUE if R is a virtual register.  */
2801 static inline bool
2802 is_virtual_register (rtx r)
2803 {
2804   return (GET_CODE (r) == REG
2805           && REGNO (r) >= 8
2806           && REGNO (r) < 32);
2807 }
2808
2809 /* In all these alloc routines, we expect the following: the insn
2810    pattern is unshared, the insn was previously recognized and failed
2811    due to predicates or constraints, and the operand data is in
2812    recog_data.  */
2813
2814 static int virt_insn_was_frame;
2815
2816 /* Hook for all insns we emit.  Re-mark them as FRAME_RELATED if
2817    needed.  */
2818 static rtx
2819 EM2 (int line ATTRIBUTE_UNUSED, rtx r)
2820 {
2821 #if DEBUG_ALLOC
2822   fprintf (stderr, "\033[36m%d: ", line);
2823   debug_rtx (r);
2824   fprintf (stderr, "\033[0m");
2825 #endif
2826   /*SCHED_GROUP_P (r) = 1;*/
2827   if (virt_insn_was_frame)
2828     RTX_FRAME_RELATED_P (r) = 1;
2829   return r;
2830 }
2831
2832 #define EM(x) EM2 (__LINE__, x)
2833
2834 /* Return a suitable RTX for the low half of a __far address.  */
2835 static rtx
2836 rl78_lo16 (rtx addr)
2837 {
2838   rtx r;
2839
2840   if (GET_CODE (addr) == SYMBOL_REF
2841       || GET_CODE (addr) == CONST)
2842     {
2843       r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0));
2844       r = gen_rtx_CONST (HImode, r);
2845     }
2846   else
2847     r = rl78_subreg (HImode, addr, SImode, 0);
2848
2849   r = gen_es_addr (r);
2850   cfun->machine->uses_es = true;
2851
2852   return r;
2853 }
2854
2855 /* Return a suitable RTX for the high half's lower byte of a __far address.  */
2856 static rtx
2857 rl78_hi8 (rtx addr)
2858 {
2859   if (GET_CODE (addr) == SYMBOL_REF
2860       || GET_CODE (addr) == CONST)
2861     {
2862       rtx r = gen_rtx_ZERO_EXTRACT (QImode, addr, GEN_INT (8), GEN_INT (16));
2863       r = gen_rtx_CONST (QImode, r);
2864       return r;
2865     }
2866   return rl78_subreg (QImode, addr, SImode, 2);
2867 }
2868
2869 static void
2870 add_postponed_content_update (rtx to, rtx value)
2871 {
2872   unsigned char index;
2873
2874   if ((index = get_content_index (to)) == NOT_KNOWN)
2875     return;
2876
2877   gcc_assert (saved_update_index == NOT_KNOWN);
2878   saved_update_index = index;
2879   saved_update_value = get_content_index (value);
2880   saved_update_mode  = GET_MODE (to);
2881 }
2882
2883 static void
2884 process_postponed_content_update (void)
2885 {
2886   if (saved_update_index != NOT_KNOWN)
2887     {
2888       update_content (saved_update_index, saved_update_value, saved_update_mode);
2889       saved_update_index = NOT_KNOWN;
2890     }
2891 }
2892
2893 /* Generate and emit a move of (register) FROM into TO.  if WHERE is not NULL
2894    then if BEFORE is true then emit the insn before WHERE, otherwise emit it
2895    after WHERE.  If TO already contains FROM then do nothing.  Returns TO if
2896    BEFORE is true, FROM otherwise.  */
2897 static rtx
2898 gen_and_emit_move (rtx to, rtx from, rtx_insn *where, bool before)
2899 {
2900   machine_mode mode = GET_MODE (to);
2901
2902   if (optimize && before && already_contains (to, from))
2903     {
2904 #if DEBUG_ALLOC
2905       display_content_memory (stderr);
2906 #endif
2907       if (dump_file)
2908         {
2909           fprintf (dump_file, " Omit move of %s into ",
2910                    get_content_name (get_content_index (from), mode));
2911           fprintf (dump_file, "%s as it already contains this value\n",
2912                    get_content_name (get_content_index (to), mode));
2913         }
2914     }
2915   else
2916     {
2917       rtx move = mode == QImode ? gen_movqi (to, from) : gen_movhi (to, from);
2918
2919       EM (move);
2920
2921       if (where == NULL_RTX)
2922         emit_insn (move);
2923       else if (before)
2924         emit_insn_before (move, where);
2925       else
2926         {
2927           rtx note = find_reg_note (where, REG_EH_REGION, NULL_RTX);
2928
2929           /* If necessary move REG_EH_REGION notes forward.
2930              cf. compiling gcc.dg/pr44545.c.  */
2931           if (note != NULL_RTX)
2932             {
2933               add_reg_note (move, REG_EH_REGION, XEXP (note, 0));
2934               remove_note (where, note);
2935             }
2936
2937           emit_insn_after (move, where);
2938         }
2939
2940       if (before)
2941         record_content (to, from);
2942       else
2943         add_postponed_content_update (to, from);
2944     }
2945
2946   return before ? to : from;
2947 }
2948
2949 /* If M is MEM(REG) or MEM(PLUS(REG,INT)) and REG is virtual then
2950    copy it into NEWBASE and return the updated MEM.  Otherwise just
2951    return M.  Any needed insns are emitted before BEFORE.  */
2952 static rtx
2953 transcode_memory_rtx (rtx m, rtx newbase, rtx_insn *before)
2954 {
2955   rtx base, index, addendr;
2956   int addend = 0;
2957   int need_es = 0;
2958
2959   if (! MEM_P (m))
2960     return m;
2961
2962   if (GET_MODE (XEXP (m, 0)) == SImode)
2963     {
2964       rtx new_m;
2965       rtx seg = rl78_hi8 (XEXP (m, 0));
2966
2967       if (!TARGET_ES0)
2968         {
2969           emit_insn_before (EM (gen_movqi (A, seg)), before);
2970           emit_insn_before (EM (gen_movqi_to_es (A)), before);
2971         }
2972
2973       record_content (A, NULL_RTX);
2974
2975       new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
2976       MEM_COPY_ATTRIBUTES (new_m, m);
2977       m = new_m;
2978       need_es = 1;
2979     }
2980
2981   characterize_address (XEXP (m, 0), & base, & index, & addendr);
2982   gcc_assert (index == NULL_RTX);
2983
2984   if (base == NULL_RTX)
2985     return m;
2986
2987   if (addendr && GET_CODE (addendr) == CONST_INT)
2988     addend = INTVAL (addendr);
2989
2990   gcc_assert (REG_P (base));
2991   gcc_assert (REG_P (newbase));
2992
2993   int limit = 256 - GET_MODE_SIZE (GET_MODE (m));
2994
2995   if (REGNO (base) == SP_REG)
2996     {
2997       if (addend >= 0 && addend <= limit)
2998         return m;
2999     }
3000
3001   /* BASE should be a virtual register.  We copy it to NEWBASE.  If
3002      the addend is out of range for DE/HL, we use AX to compute the full
3003      address.  */
3004
3005   if (addend < 0
3006       || (addend > limit && REGNO (newbase) != BC_REG)
3007       || (addendr
3008           && (GET_CODE (addendr) != CONST_INT)
3009           && ((REGNO (newbase) != BC_REG))
3010           ))
3011     {
3012       /* mov ax, vreg
3013          add ax, #imm
3014          mov hl, ax     */
3015       EM (emit_insn_before (gen_movhi (AX, base), before));
3016       EM (emit_insn_before (gen_addhi3 (AX, AX, addendr), before));
3017       EM (emit_insn_before (gen_movhi (newbase, AX), before));
3018       record_content (AX, NULL_RTX);
3019       record_content (newbase, NULL_RTX);
3020
3021       base = newbase;
3022       addend = 0;
3023       addendr = 0;
3024     }
3025   else
3026     {
3027       base = gen_and_emit_move (newbase, base, before, true);
3028     }
3029
3030   if (addend)
3031     {
3032       record_content (base, NULL_RTX);
3033       base = gen_rtx_PLUS (HImode, base, GEN_INT (addend));
3034     }
3035   else if (addendr)
3036     {
3037       record_content (base, NULL_RTX);
3038       base = gen_rtx_PLUS (HImode, base, addendr);
3039     }
3040
3041   if (need_es)
3042     {
3043       m = change_address (m, GET_MODE (m), gen_es_addr (base));
3044       cfun->machine->uses_es = true;
3045     }
3046   else
3047     m = change_address (m, GET_MODE (m), base);
3048   return m;
3049 }
3050
3051 /* Copy SRC to accumulator (A or AX), placing any generated insns
3052    before BEFORE.  Returns accumulator RTX.  */
3053 static rtx
3054 move_to_acc (int opno, rtx_insn *before)
3055 {
3056   rtx src = OP (opno);
3057   machine_mode mode = GET_MODE (src);
3058
3059   if (REG_P (src) && REGNO (src) < 2)
3060     return src;
3061
3062   if (mode == VOIDmode)
3063     mode = recog_data.operand_mode[opno];
3064
3065   return gen_and_emit_move (mode == QImode ? A : AX, src, before, true);
3066 }
3067
3068 static void
3069 force_into_acc (rtx src, rtx_insn *before)
3070 {
3071   machine_mode mode = GET_MODE (src);
3072   rtx move;
3073
3074   if (REG_P (src) && REGNO (src) < 2)
3075     return;
3076
3077   move = mode == QImode ? gen_movqi (A, src) : gen_movhi (AX, src);
3078
3079   EM (move);
3080
3081   emit_insn_before (move, before);
3082   record_content (AX, NULL_RTX);
3083 }
3084
3085 /* Copy accumulator (A or AX) to DEST, placing any generated insns
3086    after AFTER.  Returns accumulator RTX.  */
3087 static rtx
3088 move_from_acc (unsigned int opno, rtx_insn *after)
3089 {
3090   rtx dest = OP (opno);
3091   machine_mode mode = GET_MODE (dest);
3092
3093   if (REG_P (dest) && REGNO (dest) < 2)
3094     return dest;
3095
3096   return gen_and_emit_move (dest, mode == QImode ? A : AX, after, false);
3097 }
3098
3099 /* Copy accumulator (A or AX) to REGNO, placing any generated insns
3100    before BEFORE.  Returns reg RTX.  */
3101 static rtx
3102 move_acc_to_reg (rtx acc, int regno, rtx_insn *before)
3103 {
3104   machine_mode mode = GET_MODE (acc);
3105   rtx reg;
3106
3107   reg = gen_rtx_REG (mode, regno);
3108
3109   return gen_and_emit_move (reg, acc, before, true);
3110 }
3111
3112 /* Copy SRC to X, placing any generated insns before BEFORE.
3113    Returns X RTX.  */
3114 static rtx
3115 move_to_x (int opno, rtx_insn *before)
3116 {
3117   rtx src = OP (opno);
3118   machine_mode mode = GET_MODE (src);
3119   rtx reg;
3120
3121   if (mode == VOIDmode)
3122     mode = recog_data.operand_mode[opno];
3123   reg = (mode == QImode) ? X : AX;
3124
3125   if (mode == QImode || ! is_virtual_register (OP (opno)))
3126     {
3127       OP (opno) = move_to_acc (opno, before);
3128       OP (opno) = move_acc_to_reg (OP (opno), X_REG, before);
3129       return reg;
3130     }
3131
3132   return gen_and_emit_move (reg, src, before, true);
3133 }
3134
3135 /* Copy OP (opno) to H or HL, placing any generated insns before BEFORE.
3136    Returns H/HL RTX.  */
3137 static rtx
3138 move_to_hl (int opno, rtx_insn *before)
3139 {
3140   rtx src = OP (opno);
3141   machine_mode mode = GET_MODE (src);
3142   rtx reg;
3143
3144   if (mode == VOIDmode)
3145     mode = recog_data.operand_mode[opno];
3146   reg = (mode == QImode) ? L : HL;
3147
3148   if (mode == QImode || ! is_virtual_register (OP (opno)))
3149     {
3150       OP (opno) = move_to_acc (opno, before);
3151       OP (opno) = move_acc_to_reg (OP (opno), L_REG, before);
3152       return reg;
3153     }
3154
3155   return gen_and_emit_move (reg, src, before, true);
3156 }
3157
3158 /* Copy OP (opno) to E or DE, placing any generated insns before BEFORE.
3159    Returns E/DE RTX.  */
3160 static rtx
3161 move_to_de (int opno, rtx_insn *before)
3162 {
3163   rtx src = OP (opno);
3164   machine_mode mode = GET_MODE (src);
3165   rtx reg;
3166
3167   if (mode == VOIDmode)
3168     mode = recog_data.operand_mode[opno];
3169
3170   reg = (mode == QImode) ? E : DE;
3171
3172   if (mode == QImode || ! is_virtual_register (OP (opno)))
3173     {
3174       OP (opno) = move_to_acc (opno, before);
3175       OP (opno) = move_acc_to_reg (OP (opno), E_REG, before);
3176     }
3177   else
3178     {
3179       gen_and_emit_move (reg, src, before, true);
3180     }
3181
3182   return reg;
3183 }
3184
3185 /* Devirtualize an insn of the form (SET (op) (unop (op))).  */
3186 static void
3187 rl78_alloc_physical_registers_op1 (rtx_insn * insn)
3188 {
3189   /* op[0] = func op[1] */
3190
3191   /* We first try using A as the destination, then copying it
3192      back.  */
3193   if (rtx_equal_p (OP (0), OP (1)))
3194     {
3195       OP (0) =
3196       OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3197     }
3198   else
3199     {
3200       /* If necessary, load the operands into BC and HL.
3201          Check to see if we already have OP (0) in HL
3202          and if so, swap the order.
3203
3204          It is tempting to perform this optimization when OP(0) does
3205          not hold a MEM, but this leads to bigger code in general.
3206          The problem is that if OP(1) holds a MEM then swapping it
3207          into BC means a BC-relative load is used and these are 3
3208          bytes long vs 1 byte for an HL load.  */
3209       if (MEM_P (OP (0))
3210           && already_contains (HL, XEXP (OP (0), 0)))
3211         {
3212           OP (0) = transcode_memory_rtx (OP (0), HL, insn);
3213           OP (1) = transcode_memory_rtx (OP (1), BC, insn);
3214         }
3215       else
3216         {
3217           OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3218           OP (1) = transcode_memory_rtx (OP (1), HL, insn);
3219         }
3220     }
3221
3222   MAYBE_OK (insn);
3223
3224   OP (0) = move_from_acc (0, insn);
3225
3226   MAYBE_OK (insn);
3227
3228   /* Try copying the src to acc first, then.  This is for, for
3229      example, ZERO_EXTEND or NOT.  */
3230   OP (1) = move_to_acc (1, insn);
3231
3232   MUST_BE_OK (insn);
3233 }
3234
3235 /* Returns true if operand OPNUM contains a constraint of type CONSTRAINT.
3236    Assumes that the current insn has already been recognised and hence the
3237    constraint data has been filled in.  */
3238 static bool
3239 has_constraint (unsigned int opnum, enum constraint_num constraint)
3240 {
3241   const char * p = recog_data.constraints[opnum];
3242
3243   /* No constraints means anything is accepted.  */
3244   if (p == NULL || *p == 0 || *p == ',')
3245     return true;
3246
3247   do
3248     {
3249       char c;
3250       unsigned int len;
3251
3252       c = *p;
3253       len = CONSTRAINT_LEN (c, p);
3254       gcc_assert (len > 0);
3255
3256       switch (c)
3257         {
3258         case 0:
3259         case ',':
3260           return false;
3261         default:
3262           if (lookup_constraint (p) == constraint)
3263             return true;
3264         }
3265       p += len;
3266     }
3267   while (1);
3268 }
3269
3270 /* Devirtualize an insn of the form (SET (op) (binop (op) (op))).  */
3271 static void
3272 rl78_alloc_physical_registers_op2 (rtx_insn * insn)
3273 {
3274   rtx_insn *prev;
3275   rtx_insn *first;
3276   bool hl_used;
3277   int tmp_id;
3278   rtx saved_op1;
3279
3280   if (rtx_equal_p (OP (0), OP (1)))
3281     {
3282       if (MEM_P (OP (2)))
3283         {
3284           OP (0) =
3285           OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3286           OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3287         }
3288       else
3289         {
3290           OP (0) =
3291           OP (1) = transcode_memory_rtx (OP (1), HL, insn);
3292           OP (2) = transcode_memory_rtx (OP (2), DE, insn);
3293         }
3294     }
3295   else if (rtx_equal_p (OP (0), OP (2)))
3296     {
3297       OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3298       OP (0) =
3299       OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3300     }
3301   else
3302     {
3303       OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3304       OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3305       OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3306     }
3307
3308   MAYBE_OK (insn);
3309
3310   prev = prev_nonnote_nondebug_insn (insn);
3311   if (recog_data.constraints[1][0] == '%'
3312       && is_virtual_register (OP (1))
3313       && ! is_virtual_register (OP (2))
3314       && ! CONSTANT_P (OP (2)))
3315     {
3316       rtx tmp = OP (1);
3317       OP (1) = OP (2);
3318       OP (2) = tmp;
3319     }
3320
3321   /* Make a note of whether (H)L is being used.  It matters
3322      because if OP (2) also needs reloading, then we must take
3323      care not to corrupt HL.  */
3324   hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1));
3325
3326   /* If HL is not currently being used and dest == op1 then there are
3327      some possible optimizations available by reloading one of the
3328      operands into HL, before trying to use the accumulator.  */
3329   if (optimize
3330       && ! hl_used
3331       && rtx_equal_p (OP (0), OP (1)))
3332     {
3333       /* If op0 is a Ws1 type memory address then switching the base
3334          address register to HL might allow us to perform an in-memory
3335          operation.  (eg for the INCW instruction).
3336
3337          FIXME: Adding the move into HL is costly if this optimization is not
3338          going to work, so for now, make sure that we know that the new insn will
3339          match the requirements of the addhi3_real pattern.  Really we ought to
3340          generate a candidate sequence, test that, and then install it if the
3341          results are good.  */
3342       if (satisfies_constraint_Ws1 (OP (0))
3343           && has_constraint (0, CONSTRAINT_Wh1)
3344           && (satisfies_constraint_K (OP (2)) || satisfies_constraint_L (OP (2))))
3345         {
3346           rtx base, index, addend, newbase;
3347
3348           characterize_address (XEXP (OP (0), 0), & base, & index, & addend);
3349           gcc_assert (index == NULL_RTX);
3350           gcc_assert (REG_P (base) && REGNO (base) == SP_REG);
3351
3352           /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset.  */
3353           if (addend != NULL_RTX)
3354             {
3355               newbase = gen_and_emit_move (HL, base, insn, true);
3356               record_content (newbase, NULL_RTX);
3357               newbase = gen_rtx_PLUS (HImode, newbase, addend);
3358
3359               OP (0) = OP (1) = change_address (OP (0), VOIDmode, newbase);
3360
3361               /* We do not want to fail here as this means that
3362                  we have inserted useless insns into the stream.  */
3363               MUST_BE_OK (insn);
3364             }
3365         }
3366       else if (REG_P (OP (0))
3367                && satisfies_constraint_Ws1 (OP (2))
3368                && has_constraint (2, CONSTRAINT_Wh1))
3369         {
3370           rtx base, index, addend, newbase;
3371
3372           characterize_address (XEXP (OP (2), 0), & base, & index, & addend);
3373           gcc_assert (index == NULL_RTX);
3374           gcc_assert (REG_P (base) && REGNO (base) == SP_REG);
3375
3376           /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset.  */
3377           if (addend != NULL_RTX)
3378             {
3379               gen_and_emit_move (HL, base, insn, true);
3380
3381               if (REGNO (OP (0)) != X_REG)
3382                 {
3383                   OP (1) = move_to_acc (1, insn);
3384                   OP (0) = move_from_acc (0, insn);
3385                 }
3386
3387               record_content (HL, NULL_RTX);
3388               newbase = gen_rtx_PLUS (HImode, HL, addend);
3389
3390               OP (2) = change_address (OP (2), VOIDmode, newbase);
3391
3392               /* We do not want to fail here as this means that
3393                  we have inserted useless insns into the stream.  */
3394               MUST_BE_OK (insn);
3395             }
3396         }
3397     }
3398
3399   OP (0) = move_from_acc (0, insn);
3400
3401   tmp_id = get_max_insn_count ();
3402   saved_op1 = OP (1);
3403
3404   if (rtx_equal_p (OP (1), OP (2)))
3405     OP (2) = OP (1) = move_to_acc (1, insn);
3406   else
3407     OP (1) = move_to_acc (1, insn);
3408
3409   MAYBE_OK (insn);
3410
3411   /* If we omitted the move of OP1 into the accumulator (because
3412      it was already there from a previous insn), then force the
3413      generation of the move instruction now.  We know that we
3414      are about to emit a move into HL (or DE) via AX, and hence
3415      our optimization to remove the load of OP1 is no longer valid.  */
3416   if (tmp_id == get_max_insn_count ())
3417     force_into_acc (saved_op1, insn);
3418
3419   /* We have to copy op2 to HL (or DE), but that involves AX, which
3420      already has a live value.  Emit it before those insns.  */
3421
3422   if (prev)
3423     first = next_nonnote_nondebug_insn (prev);
3424   else
3425     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3426       ;
3427
3428   OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first);
3429
3430   MUST_BE_OK (insn);
3431 }
3432
3433 /* Devirtualize an insn of the form SET (PC) (MEM/REG).  */
3434 static void
3435 rl78_alloc_physical_registers_ro1 (rtx_insn * insn)
3436 {
3437   OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3438
3439   MAYBE_OK (insn);
3440
3441   OP (0) = move_to_acc (0, insn);
3442
3443   MUST_BE_OK (insn);
3444 }
3445
3446 /* Devirtualize a compare insn.  */
3447 static void
3448 rl78_alloc_physical_registers_cmp (rtx_insn * insn)
3449 {
3450   int tmp_id;
3451   rtx saved_op1;
3452   rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
3453   rtx_insn *first;
3454
3455   OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3456   OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3457
3458   /* HI compares have to have OP (1) in AX, but QI
3459      compares do not, so it is worth checking here.  */
3460   MAYBE_OK (insn);
3461
3462   /* For an HImode compare, OP (1) must always be in AX.
3463      But if OP (1) is a REG (and not AX), then we can avoid
3464      a reload of OP (1) if we reload OP (2) into AX and invert
3465      the comparison.  */
3466   if (REG_P (OP (1))
3467       && REGNO (OP (1)) != AX_REG
3468       && GET_MODE (OP (1)) == HImode
3469       && MEM_P (OP (2)))
3470     {
3471       rtx cmp = XEXP (SET_SRC (PATTERN (insn)), 0);
3472
3473       OP (2) = move_to_acc (2, insn);
3474
3475       switch (GET_CODE (cmp))
3476         {
3477         case EQ:
3478         case NE:
3479           break;
3480         case LTU: cmp = gen_rtx_GTU (HImode, OP (2), OP (1)); break;
3481         case GTU: cmp = gen_rtx_LTU (HImode, OP (2), OP (1)); break;
3482         case LEU: cmp = gen_rtx_GEU (HImode, OP (2), OP (1)); break;
3483         case GEU: cmp = gen_rtx_LEU (HImode, OP (2), OP (1)); break;
3484
3485         case LT:
3486         case GT:
3487         case LE:
3488         case GE:
3489 #if DEBUG_ALLOC
3490           debug_rtx (insn);
3491 #endif
3492         default:
3493           gcc_unreachable ();
3494         }
3495
3496       if (GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
3497         PATTERN (insn) = gen_cbranchhi4_real (cmp, OP (2), OP (1), OP (3));
3498       else
3499         PATTERN (insn) = gen_cbranchhi4_real_inverted (cmp, OP (2), OP (1), OP (3));
3500
3501       MUST_BE_OK (insn);
3502     }
3503
3504   /* Surprisingly, gcc can generate a comparison of a register with itself, but this
3505      should be handled by the second alternative of the cbranchhi_real pattern.  */
3506   if (rtx_equal_p (OP (1), OP (2)))
3507     {
3508       OP (1) = OP (2) = BC;
3509       MUST_BE_OK (insn);
3510     }
3511
3512   tmp_id = get_max_insn_count ();
3513   saved_op1 = OP (1);
3514
3515   OP (1) = move_to_acc (1, insn);
3516
3517   MAYBE_OK (insn);
3518
3519   /* If we omitted the move of OP1 into the accumulator (because
3520      it was already there from a previous insn), then force the
3521      generation of the move instruction now.  We know that we
3522      are about to emit a move into HL via AX, and hence our
3523      optimization to remove the load of OP1 is no longer valid.  */
3524   if (tmp_id == get_max_insn_count ())
3525     force_into_acc (saved_op1, insn);
3526
3527   /* We have to copy op2 to HL, but that involves the acc, which
3528      already has a live value.  Emit it before those insns.  */
3529   if (prev)
3530     first = next_nonnote_nondebug_insn (prev);
3531   else
3532     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3533       ;
3534   OP (2) = move_to_hl (2, first);
3535
3536   MUST_BE_OK (insn);
3537 }
3538
3539 /* Like op2, but AX = A * X.  */
3540 static void
3541 rl78_alloc_physical_registers_umul (rtx_insn * insn)
3542 {
3543   rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
3544   rtx_insn *first;
3545   int tmp_id;
3546   rtx saved_op1;
3547
3548   OP (0) = transcode_memory_rtx (OP (0), BC, insn);
3549   OP (1) = transcode_memory_rtx (OP (1), DE, insn);
3550   OP (2) = transcode_memory_rtx (OP (2), HL, insn);
3551
3552   MAYBE_OK (insn);
3553
3554   if (recog_data.constraints[1][0] == '%'
3555       && is_virtual_register (OP (1))
3556       && !is_virtual_register (OP (2))
3557       && !CONSTANT_P (OP (2)))
3558     {
3559       rtx tmp = OP (1);
3560       OP (1) = OP (2);
3561       OP (2) = tmp;
3562     }
3563
3564   OP (0) = move_from_acc (0, insn);
3565
3566   tmp_id = get_max_insn_count ();
3567   saved_op1 = OP (1);
3568
3569   if (rtx_equal_p (OP (1), OP (2)))
3570     {
3571       gcc_assert (GET_MODE (OP (2)) == QImode);
3572       /* The MULU instruction does not support duplicate arguments
3573          but we know that if we copy OP (2) to X it will do so via
3574          A and thus OP (1) will already be loaded into A.  */
3575       OP (2) = move_to_x (2, insn);
3576       OP (1) = A;
3577     }
3578   else
3579     OP (1) = move_to_acc (1, insn);
3580
3581   MAYBE_OK (insn);
3582
3583   /* If we omitted the move of OP1 into the accumulator (because
3584      it was already there from a previous insn), then force the
3585      generation of the move instruction now.  We know that we
3586      are about to emit a move into HL (or DE) via AX, and hence
3587      our optimization to remove the load of OP1 is no longer valid.  */
3588   if (tmp_id == get_max_insn_count ())
3589     force_into_acc (saved_op1, insn);
3590
3591   /* We have to copy op2 to X, but that involves the acc, which
3592      already has a live value.  Emit it before those insns.  */
3593
3594   if (prev)
3595     first = next_nonnote_nondebug_insn (prev);
3596   else
3597     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
3598       ;
3599   OP (2) = move_to_x (2, first);
3600
3601   MUST_BE_OK (insn);
3602 }
3603
3604 static void
3605 rl78_alloc_address_registers_macax (rtx_insn * insn)
3606 {
3607   int which, op;
3608   bool replace_in_op0 = false;
3609   bool replace_in_op1 = false;
3610
3611   MAYBE_OK (insn);
3612
3613   /* Two different MEMs are not allowed.  */
3614   which = 0;
3615   for (op = 2; op >= 0; op --)
3616     {
3617       if (MEM_P (OP (op)))
3618         {
3619           if (op == 0 && replace_in_op0)
3620             continue;
3621           if (op == 1 && replace_in_op1)
3622             continue;
3623
3624           switch (which)
3625             {
3626             case 0:
3627               /* If we replace a MEM, make sure that we replace it for all
3628                  occurrences of the same MEM in the insn.  */
3629               replace_in_op0 = (op > 0 && rtx_equal_p (OP (op), OP (0)));
3630               replace_in_op1 = (op > 1 && rtx_equal_p (OP (op), OP (1)));
3631
3632               OP (op) = transcode_memory_rtx (OP (op), HL, insn);
3633               if (op == 2
3634                   && MEM_P (OP (op))
3635                   && ((GET_CODE (XEXP (OP (op), 0)) == REG
3636                        && REGNO (XEXP (OP (op), 0)) == SP_REG)
3637                       || (GET_CODE (XEXP (OP (op), 0)) == PLUS
3638                           && REGNO (XEXP (XEXP (OP (op), 0), 0)) == SP_REG)))
3639                 {
3640                   emit_insn_before (gen_movhi (HL, gen_rtx_REG (HImode, SP_REG)), insn);
3641                   OP (op) = replace_rtx (OP (op), gen_rtx_REG (HImode, SP_REG), HL);
3642                 }
3643               if (replace_in_op0)
3644                 OP (0) = OP (op);
3645               if (replace_in_op1)
3646                 OP (1) = OP (op);
3647               break;
3648             case 1:
3649               OP (op) = transcode_memory_rtx (OP (op), DE, insn);
3650               break;
3651             case 2:
3652               OP (op) = transcode_memory_rtx (OP (op), BC, insn);
3653               break;
3654             }
3655           which ++;
3656         }
3657     }
3658
3659   MUST_BE_OK (insn);
3660 }
3661
3662 static void
3663 rl78_alloc_address_registers_div (rtx_insn * insn)
3664 {
3665   MUST_BE_OK (insn);
3666 }
3667
3668 /* Scan all insns and devirtualize them.  */
3669 static void
3670 rl78_alloc_physical_registers (void)
3671 {
3672   /* During most of the compile, gcc is dealing with virtual
3673      registers.  At this point, we need to assign physical registers
3674      to the vitual ones, and copy in/out as needed.  */
3675
3676   rtx_insn *insn, *curr;
3677   enum attr_valloc valloc_method;
3678
3679   for (insn = get_insns (); insn; insn = curr)
3680     {
3681       int i;
3682
3683       curr = next_nonnote_nondebug_insn (insn);
3684
3685       if (INSN_P (insn)
3686           && (GET_CODE (PATTERN (insn)) == SET
3687               || GET_CODE (PATTERN (insn)) == CALL)
3688           && INSN_CODE (insn) == -1)
3689         {
3690           if (GET_CODE (SET_SRC (PATTERN (insn))) == ASM_OPERANDS)
3691             continue;
3692           i = recog (PATTERN (insn), insn, 0);
3693           if (i == -1)
3694             {
3695               debug_rtx (insn);
3696               gcc_unreachable ();
3697             }
3698           INSN_CODE (insn) = i;
3699         }
3700     }
3701
3702   cfun->machine->virt_insns_ok = 0;
3703   cfun->machine->real_insns_ok = 1;
3704
3705   clear_content_memory ();
3706
3707   for (insn = get_insns (); insn; insn = curr)
3708     {
3709       rtx pattern;
3710
3711       curr = insn ? next_nonnote_nondebug_insn (insn) : NULL;
3712
3713       if (!INSN_P (insn))
3714         {
3715           if (LABEL_P (insn))
3716             clear_content_memory ();
3717
3718           continue;
3719         }
3720
3721       if (dump_file)
3722         fprintf (dump_file, "Converting insn %d\n", INSN_UID (insn));
3723
3724       pattern = PATTERN (insn);
3725       if (GET_CODE (pattern) == PARALLEL)
3726         pattern = XVECEXP (pattern, 0, 0);
3727       if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL)
3728         clear_content_memory ();
3729       if (GET_CODE (pattern) != SET
3730           && GET_CODE (pattern) != CALL)
3731         continue;
3732       if (GET_CODE (pattern) == SET
3733           && GET_CODE (SET_SRC (pattern)) == ASM_OPERANDS)
3734         continue;
3735
3736       valloc_method = get_attr_valloc (insn);
3737
3738       PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
3739
3740       if (valloc_method == VALLOC_MACAX)
3741         {
3742           record_content (AX, NULL_RTX);
3743           record_content (BC, NULL_RTX);
3744           record_content (DE, NULL_RTX);
3745         }
3746       else if (valloc_method == VALLOC_DIVHI)
3747         {
3748           record_content (AX, NULL_RTX);
3749           record_content (BC, NULL_RTX);
3750         }
3751       else if (valloc_method == VALLOC_DIVSI)
3752         {
3753           record_content (AX, NULL_RTX);
3754           record_content (BC, NULL_RTX);
3755           record_content (DE, NULL_RTX);
3756           record_content (HL, NULL_RTX);
3757         }
3758
3759       if (insn_ok_now (insn))
3760         continue;
3761
3762       INSN_CODE (insn) = -1;
3763
3764       if (RTX_FRAME_RELATED_P (insn))
3765         virt_insn_was_frame = 1;
3766       else
3767         virt_insn_was_frame = 0;
3768
3769       switch (valloc_method)
3770         {
3771         case VALLOC_OP1:
3772           rl78_alloc_physical_registers_op1 (insn);
3773           break;
3774         case VALLOC_OP2:
3775           rl78_alloc_physical_registers_op2 (insn);
3776           break;
3777         case VALLOC_RO1:
3778           rl78_alloc_physical_registers_ro1 (insn);
3779           break;
3780         case VALLOC_CMP:
3781           rl78_alloc_physical_registers_cmp (insn);
3782           break;
3783         case VALLOC_UMUL:
3784           rl78_alloc_physical_registers_umul (insn);
3785           record_content (AX, NULL_RTX);
3786           break;
3787         case VALLOC_MACAX:
3788           /* Macro that clobbers AX.  */
3789           rl78_alloc_address_registers_macax (insn);
3790           record_content (AX, NULL_RTX);
3791           record_content (BC, NULL_RTX);
3792           record_content (DE, NULL_RTX);
3793           break;
3794         case VALLOC_DIVSI:
3795           rl78_alloc_address_registers_div (insn);
3796           record_content (AX, NULL_RTX);
3797           record_content (BC, NULL_RTX);
3798           record_content (DE, NULL_RTX);
3799           record_content (HL, NULL_RTX);
3800           break;
3801         case VALLOC_DIVHI:
3802           rl78_alloc_address_registers_div (insn);
3803           record_content (AX, NULL_RTX);
3804           record_content (BC, NULL_RTX);
3805           break;
3806         default:
3807           gcc_unreachable ();
3808         }
3809
3810       if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL)
3811         clear_content_memory ();
3812       else
3813         process_postponed_content_update ();
3814     }
3815
3816 #if DEBUG_ALLOC
3817   fprintf (stderr, "\033[0m");
3818 #endif
3819 }
3820
3821 /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN.
3822    This function scans for uses of registers; the last use (i.e. first
3823    encounter when scanning backwards) triggers a REG_DEAD note if the
3824    reg was previously in DEAD[].  */
3825 static void
3826 rl78_note_reg_uses (char *dead, rtx s, rtx insn)
3827 {
3828   const char *fmt;
3829   int i, r;
3830   enum rtx_code code;
3831
3832   if (!s)
3833     return;
3834
3835   code = GET_CODE (s);
3836
3837   switch (code)
3838     {
3839       /* Compare registers by number.  */
3840     case REG:
3841       r = REGNO (s);
3842       if (dump_file)
3843         {
3844           fprintf (dump_file, "note use reg %d size %d on insn %d\n",
3845                    r, GET_MODE_SIZE (GET_MODE (s)), INSN_UID (insn));
3846           print_rtl_single (dump_file, s);
3847         }
3848       if (dead [r])
3849         add_reg_note (insn, REG_DEAD, gen_rtx_REG (GET_MODE (s), r));
3850       for (i = 0; i < GET_MODE_SIZE (GET_MODE (s)); i ++)
3851         dead [r + i] = 0;
3852       return;
3853
3854       /* These codes have no constituent expressions
3855          and are unique.  */
3856     case SCRATCH:
3857     case CC0:
3858     case PC:
3859       return;
3860
3861     case CONST_INT:
3862     case CONST_VECTOR:
3863     case CONST_DOUBLE:
3864     case CONST_FIXED:
3865       /* These are kept unique for a given value.  */
3866       return;
3867
3868     default:
3869       break;
3870     }
3871
3872   fmt = GET_RTX_FORMAT (code);
3873
3874   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3875     {
3876       if (fmt[i] == 'E')
3877         {
3878           int j;
3879           for (j = XVECLEN (s, i) - 1; j >= 0; j--)
3880             rl78_note_reg_uses (dead, XVECEXP (s, i, j), insn);
3881         }
3882       else if (fmt[i] == 'e')
3883         rl78_note_reg_uses (dead, XEXP (s, i), insn);
3884     }
3885 }
3886
3887 /* Like the previous function, but scan for SETs instead.  */
3888 static void
3889 rl78_note_reg_set (char *dead, rtx d, rtx insn)
3890 {
3891   int r, i;
3892   bool is_dead;
3893   if (GET_CODE (d) == MEM)
3894     rl78_note_reg_uses (dead, XEXP (d, 0), insn);
3895
3896   if (GET_CODE (d) != REG)
3897     return;
3898
3899   /* Do not mark the reg unused unless all QImode parts of it are dead.  */
3900   r = REGNO (d);
3901   is_dead = true;
3902   for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++)
3903           if (!dead [r + i])
3904                   is_dead = false;
3905   if(is_dead)
3906         add_reg_note (insn, REG_UNUSED, gen_rtx_REG (GET_MODE (d), r));
3907   if (dump_file)
3908     fprintf (dump_file, "note set reg %d size %d\n", r, GET_MODE_SIZE (GET_MODE (d)));
3909   for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++)
3910     dead [r + i] = 1;
3911 }
3912
3913 /* This is a rather crude register death pass.  Death status is reset
3914    at every jump or call insn.  */
3915 static void
3916 rl78_calculate_death_notes (void)
3917 {
3918   char dead[FIRST_PSEUDO_REGISTER];
3919   rtx p, s, d;
3920 rtx_insn *insn;
3921   int i;
3922
3923   memset (dead, 0, sizeof (dead));
3924
3925   for (insn = get_last_insn ();
3926        insn;
3927        insn = prev_nonnote_nondebug_insn (insn))
3928     {
3929       if (dump_file)
3930         {
3931           fprintf (dump_file, "\n--------------------------------------------------");
3932           fprintf (dump_file, "\nDead:");
3933           for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
3934             if (dead[i])
3935               fprintf (dump_file, " %s", reg_names[i]);
3936           fprintf (dump_file, "\n");
3937           print_rtl_single (dump_file, insn);
3938         }
3939
3940       switch (GET_CODE (insn))
3941         {
3942         case INSN:
3943           p = PATTERN (insn);
3944           if (GET_CODE (p) == PARALLEL)
3945             {
3946               rtx q = XVECEXP (p, 0 ,1);
3947
3948               /* This happens with the DIV patterns.  */
3949               if (GET_CODE (q) == SET)
3950                 {
3951                   s = SET_SRC (q);
3952                   d = SET_DEST (q);
3953                   rl78_note_reg_set (dead, d, insn);
3954                   rl78_note_reg_uses (dead, s, insn);
3955
3956                 }
3957               p = XVECEXP (p, 0, 0);
3958             }
3959
3960           switch (GET_CODE (p))
3961             {
3962             case SET:
3963               s = SET_SRC (p);
3964               d = SET_DEST (p);
3965               rl78_note_reg_set (dead, d, insn);
3966               rl78_note_reg_uses (dead, s, insn);
3967               break;
3968
3969             case USE:
3970               rl78_note_reg_uses (dead, p, insn);
3971               break;
3972
3973             default:
3974               break;
3975             }
3976           break;
3977
3978         case JUMP_INSN:
3979           if (INSN_CODE (insn) == CODE_FOR_rl78_return)
3980             {
3981               memset (dead, 1, sizeof (dead));
3982               /* We expect a USE just prior to this, which will mark
3983                  the actual return registers.  The USE will have a
3984                  death note, but we aren't going to be modifying it
3985                  after this pass.  */
3986               break;
3987             }
3988           /* FALLTHRU */
3989         case CALL_INSN:
3990           memset (dead, 0, sizeof (dead));
3991           break;
3992
3993         default:
3994           break;
3995         }
3996       if (dump_file)
3997         print_rtl_single (dump_file, insn);
3998     }
3999 }
4000
4001 /* Helper function to reset the origins in RP and the age in AGE for
4002    all registers.  */
4003 static void
4004 reset_origins (int *rp, int *age)
4005 {
4006   int i;
4007   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4008     {
4009       rp[i] = i;
4010       age[i] = 0;
4011     }
4012 }
4013
4014 static void
4015 set_origin (rtx pat, rtx_insn * insn, int * origins, int * age)
4016 {
4017   rtx src = SET_SRC (pat);
4018   rtx dest = SET_DEST (pat);
4019   int mb = GET_MODE_SIZE (GET_MODE (dest));
4020   int i;
4021
4022   if (GET_CODE (dest) == REG)
4023     {
4024       int dr = REGNO (dest);
4025
4026       if (GET_CODE (src) == REG)
4027         {
4028           int sr = REGNO (src);
4029           bool same = true;
4030           int best_age, best_reg;
4031
4032           /* See if the copy is not needed.  */
4033           for (i = 0; i < mb; i ++)
4034             if (origins[dr + i] != origins[sr + i])
4035               same = false;
4036
4037           if (same)
4038             {
4039               if (dump_file)
4040                 fprintf (dump_file, "deleting because dest already has correct value\n");
4041               delete_insn (insn);
4042               return;
4043             }
4044
4045           if (dr < 8 || sr >= 8)
4046             {
4047               int ar;
4048
4049               best_age = -1;
4050               best_reg = -1;
4051
4052               /* See if the copy can be made from another
4053                  bank 0 register instead, instead of the
4054                  virtual src register.  */
4055               for (ar = 0; ar < 8; ar += mb)
4056                 {
4057                   same = true;
4058
4059                   for (i = 0; i < mb; i ++)
4060                     if (origins[ar + i] != origins[sr + i])
4061                       same = false;
4062
4063                   /* The chip has some reg-reg move limitations.  */
4064                   if (mb == 1 && dr > 3)
4065                     same = false;
4066
4067                   if (same)
4068                     {
4069                       if (best_age == -1 || best_age > age[sr + i])
4070                         {
4071                           best_age = age[sr + i];
4072                           best_reg = sr;
4073                         }
4074                     }
4075                 }
4076
4077               if (best_reg != -1)
4078                 {
4079                   /* FIXME: copy debug info too.  */
4080                   SET_SRC (pat) = gen_rtx_REG (GET_MODE (src), best_reg);
4081                   sr = best_reg;
4082                 }
4083             }
4084
4085           for (i = 0; i < mb; i++)
4086             {
4087               origins[dr + i] = origins[sr + i];
4088               age[dr + i] = age[sr + i] + 1;
4089             }
4090         }
4091       else
4092         {
4093           /* The destination is computed, its origin is itself.  */
4094           if (dump_file)
4095             fprintf (dump_file, "resetting origin of r%d for %d byte%s\n",
4096                      dr, mb, mb == 1 ? "" : "s");
4097
4098           for (i = 0; i < mb; i ++)
4099             {
4100               origins[dr + i] = dr + i;
4101               age[dr + i] = 0;
4102             }
4103         }
4104
4105       /* Any registers marked with that reg as an origin are reset.  */
4106       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4107         if (origins[i] >= dr && origins[i] < dr + mb)
4108           {
4109             origins[i] = i;
4110             age[i] = 0;
4111           }
4112     }
4113
4114   /* Special case - our MUL patterns uses AX and sometimes BC.  */
4115   if (get_attr_valloc (insn) == VALLOC_MACAX)
4116     {
4117       if (dump_file)
4118         fprintf (dump_file, "Resetting origin of AX/BC for MUL pattern.\n");
4119
4120       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4121         if (i <= 3 || origins[i] <= 3)
4122           {
4123             origins[i] = i;
4124             age[i] = 0;
4125           }
4126     }
4127   else if (get_attr_valloc (insn) == VALLOC_DIVHI)
4128     {
4129       if (dump_file)
4130         fprintf (dump_file, "Resetting origin of AX/DE for DIVHI pattern.\n");
4131
4132       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4133         if (i == A_REG
4134             || i == X_REG
4135             || i == D_REG
4136             || i == E_REG
4137             || origins[i] == A_REG
4138             || origins[i] == X_REG
4139             || origins[i] == D_REG
4140             || origins[i] == E_REG)
4141           {
4142             origins[i] = i;
4143             age[i] = 0;
4144           }
4145     }
4146   else if (get_attr_valloc (insn) == VALLOC_DIVSI)
4147     {
4148       if (dump_file)
4149         fprintf (dump_file, "Resetting origin of AX/BC/DE/HL for DIVSI pattern.\n");
4150
4151       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4152         if (i <= 7 || origins[i] <= 7)
4153           {
4154             origins[i] = i;
4155             age[i] = 0;
4156           }
4157     }
4158
4159   if (GET_CODE (src) == ASHIFT
4160       || GET_CODE (src) == ASHIFTRT
4161       || GET_CODE (src) == LSHIFTRT)
4162     {
4163       rtx count = XEXP (src, 1);
4164
4165       if (GET_CODE (count) == REG)
4166         {
4167           /* Special case - our pattern clobbers the count register.  */
4168           int r = REGNO (count);
4169
4170           if (dump_file)
4171             fprintf (dump_file, "Resetting origin of r%d for shift.\n", r);
4172
4173           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4174             if (i == r || origins[i] == r)
4175               {
4176                 origins[i] = i;
4177                 age[i] = 0;
4178               }
4179         }
4180     }
4181 }
4182
4183 /* The idea behind this optimization is to look for cases where we
4184    move data from A to B to C, and instead move from A to B, and A to
4185    C.  If B is a virtual register or memory, this is a big win on its
4186    own.  If B turns out to be unneeded after this, it's a bigger win.
4187    For each register, we try to determine where it's value originally
4188    came from, if it's propogated purely through moves (and not
4189    computes).  The ORIGINS[] array has the regno for the "origin" of
4190    the value in the [regno] it's indexed by.  */
4191 static void
4192 rl78_propogate_register_origins (void)
4193 {
4194   int origins[FIRST_PSEUDO_REGISTER];
4195   int age[FIRST_PSEUDO_REGISTER];
4196   int i;
4197   rtx_insn *insn, *ninsn = NULL;
4198   rtx pat;
4199
4200   reset_origins (origins, age);
4201
4202   for (insn = get_insns (); insn; insn = ninsn)
4203     {
4204       ninsn = next_nonnote_nondebug_insn (insn);
4205
4206       if (dump_file)
4207         {
4208           fprintf (dump_file, "\n");
4209           fprintf (dump_file, "Origins:");
4210           for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
4211             if (origins[i] != i)
4212               fprintf (dump_file, " r%d=r%d", i, origins[i]);
4213           fprintf (dump_file, "\n");
4214           print_rtl_single (dump_file, insn);
4215         }
4216
4217       switch (GET_CODE (insn))
4218         {
4219         case CODE_LABEL:
4220         case BARRIER:
4221         case CALL_INSN:
4222         case JUMP_INSN:
4223           reset_origins (origins, age);
4224           break;
4225
4226         default:
4227           break;
4228
4229         case INSN:
4230           pat = PATTERN (insn);
4231
4232           if (GET_CODE (pat) == PARALLEL)
4233             {
4234               rtx clobber = XVECEXP (pat, 0, 1);
4235               pat = XVECEXP (pat, 0, 0);
4236               if (GET_CODE (clobber) == CLOBBER
4237                   && GET_CODE (XEXP (clobber, 0)) == REG)
4238                 {
4239                   int cr = REGNO (XEXP (clobber, 0));
4240                   int mb = GET_MODE_SIZE (GET_MODE (XEXP (clobber, 0)));
4241                   if (dump_file)
4242                     fprintf (dump_file, "reset origins of %d regs at %d\n", mb, cr);
4243                   for (i = 0; i < mb; i++)
4244                     {
4245                       origins[cr + i] = cr + i;
4246                       age[cr + i] = 0;
4247                     }
4248                 }
4249               /* This happens with the DIV patterns.  */
4250               else if (GET_CODE (clobber) == SET)
4251                 {
4252                   set_origin (clobber, insn, origins, age);
4253                 }
4254               else
4255                 break;
4256             }
4257
4258           if (GET_CODE (pat) == SET)
4259             {
4260               set_origin (pat, insn, origins, age);
4261             }
4262           else if (GET_CODE (pat) == CLOBBER
4263                    && GET_CODE (XEXP (pat, 0)) == REG)
4264             {
4265               if (REG_P (XEXP (pat, 0)))
4266                 {
4267                   unsigned int reg = REGNO (XEXP (pat, 0));
4268
4269                   origins[reg] = reg;
4270                   age[reg] = 0;
4271                 }
4272             }
4273         }
4274     }
4275 }
4276
4277 /* Remove any SETs where the destination is unneeded.  */
4278 static void
4279 rl78_remove_unused_sets (void)
4280 {
4281   rtx_insn *insn, *ninsn = NULL;
4282   rtx dest;
4283
4284   for (insn = get_insns (); insn; insn = ninsn)
4285     {
4286       ninsn = next_nonnote_nondebug_insn (insn);
4287
4288       rtx set = single_set (insn);
4289       if (set == NULL)
4290         continue;
4291
4292       dest = SET_DEST (set);
4293
4294       if (GET_CODE (dest) != REG || REGNO (dest) > 23)
4295         continue;
4296
4297       if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
4298         {
4299           if (dump_file)
4300             fprintf (dump_file, "deleting because the set register is never used.\n");
4301           delete_insn (insn);
4302         }
4303     }
4304 }
4305
4306 /* This is the top of the devritualization pass.  */
4307 static void
4308 rl78_reorg (void)
4309 {
4310   /* split2 only happens when optimizing, but we need all movSIs to be
4311      split now.  */
4312   if (optimize <= 0)
4313     split_all_insns ();
4314
4315   rl78_alloc_physical_registers ();
4316
4317   if (dump_file)
4318     {
4319       fprintf (dump_file, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n");
4320       print_rtl_with_bb (dump_file, get_insns (), TDF_NONE);
4321     }
4322
4323   rl78_propogate_register_origins ();
4324   rl78_calculate_death_notes ();
4325
4326   if (dump_file)
4327     {
4328       fprintf (dump_file, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n");
4329       print_rtl_with_bb (dump_file, get_insns (), TDF_NONE);
4330       fprintf (dump_file, "\n======================================================================\n");
4331     }
4332
4333   rl78_remove_unused_sets ();
4334
4335   /* The code after devirtualizing has changed so much that at this point
4336      we might as well just rescan everything.  Note that
4337      df_rescan_all_insns is not going to help here because it does not
4338      touch the artificial uses and defs.  */
4339   df_finish_pass (true);
4340   if (optimize > 1)
4341     df_live_add_problem ();
4342   df_scan_alloc (NULL);
4343   df_scan_blocks ();
4344
4345   if (optimize)
4346     df_analyze ();
4347 }
4348
4349 #undef  TARGET_RETURN_IN_MEMORY
4350 #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory
4351
4352 static bool
4353 rl78_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
4354 {
4355   const HOST_WIDE_INT size = int_size_in_bytes (type);
4356   return (size == -1 || size > 8);
4357 }
4358
4359 \f
4360 #undef  TARGET_RTX_COSTS
4361 #define TARGET_RTX_COSTS rl78_rtx_costs
4362
4363 static bool
4364 rl78_rtx_costs (rtx          x,
4365                 machine_mode mode,
4366                 int          outer_code ATTRIBUTE_UNUSED,
4367                 int          opno ATTRIBUTE_UNUSED,
4368                 int *        total,
4369                 bool         speed ATTRIBUTE_UNUSED)
4370 {
4371   int code = GET_CODE (x);
4372
4373   if (code == IF_THEN_ELSE)
4374     {
4375       *total = COSTS_N_INSNS (10);
4376       return true;
4377     }
4378
4379   if (mode == HImode)
4380     {
4381       if (code == MULT && ! speed)
4382         {
4383           * total = COSTS_N_INSNS (8);
4384           return true;
4385         }
4386       return false;
4387     }
4388
4389   if (mode == SImode)
4390     {
4391       switch (code)
4392         {
4393         case MULT:
4394           if (! speed)
4395             /* If we are compiling for space then we do not want to use the
4396                inline SImode multiplication patterns or shift sequences.
4397                The cost is not set to 1 or 5 however as we have to allow for
4398                the possibility that we might be converting a leaf function
4399                into a non-leaf function.  (There is no way to tell here).
4400                A value of 13 seems to be a reasonable compromise for the
4401                moment.  */
4402             * total = COSTS_N_INSNS (13);
4403           else if (RL78_MUL_G14)
4404             *total = COSTS_N_INSNS (14);
4405           else if (RL78_MUL_G13)
4406             *total = COSTS_N_INSNS (29);
4407           else
4408             *total = COSTS_N_INSNS (500);
4409           return true;
4410
4411         case PLUS:
4412           *total = COSTS_N_INSNS (8);
4413           return true;
4414
4415         case ASHIFT:
4416         case ASHIFTRT:
4417         case LSHIFTRT:
4418           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
4419             {
4420               switch (INTVAL (XEXP (x, 1)))
4421                 {
4422                 case 0:  *total = COSTS_N_INSNS (0);    break;
4423                 case 1:  *total = COSTS_N_INSNS (6);    break;
4424                 case 2: case 3: case 4: case 5: case 6: case 7:
4425                   *total = COSTS_N_INSNS (10); break;
4426                 case 8:  *total = COSTS_N_INSNS (6);    break;
4427                 case 9: case 10: case 11: case 12: case 13: case 14: case 15:
4428                   *total = COSTS_N_INSNS (10); break;
4429                 case 16: *total = COSTS_N_INSNS (3);    break;
4430                 case 17: case 18: case 19: case 20: case 21: case 22: case 23:
4431                   *total = COSTS_N_INSNS (4); break;
4432                 case 24: *total = COSTS_N_INSNS (4);    break;
4433                 case 25: case 26: case 27: case 28: case 29: case 30: case 31:
4434                   *total = COSTS_N_INSNS (5); break;
4435                 }
4436             }
4437           else
4438             *total = COSTS_N_INSNS (10+4*16);
4439           return true;
4440
4441         default:
4442           break;
4443         }
4444     }
4445   return false;
4446 }
4447 \f
4448
4449 static GTY(()) section * saddr_section;
4450 static GTY(()) section * frodata_section;
4451
4452 int
4453 rl78_saddr_p (rtx x)
4454 {
4455   const char * c;
4456
4457   if (MEM_P (x))
4458     x = XEXP (x, 0);
4459   if (GET_CODE (x) == PLUS)
4460     x = XEXP (x, 0);
4461   if (GET_CODE (x) != SYMBOL_REF)
4462     return 0;
4463
4464   c = XSTR (x, 0);
4465   if (memcmp (c, "@s.", 3) == 0)
4466     return 1;
4467
4468   return 0;
4469 }
4470
4471 int
4472 rl78_sfr_p (rtx x)
4473 {
4474   if (MEM_P (x))
4475     x = XEXP (x, 0);
4476   if (GET_CODE (x) != CONST_INT)
4477     return 0;
4478
4479   if ((INTVAL (x) & 0xFF00) != 0xFF00)
4480     return 0;
4481
4482   return 1;
4483 }
4484
4485 #undef  TARGET_STRIP_NAME_ENCODING
4486 #define TARGET_STRIP_NAME_ENCODING rl78_strip_name_encoding
4487
4488 static const char *
4489 rl78_strip_name_encoding (const char * sym)
4490 {
4491   while (1)
4492     {
4493       if (*sym == '*')
4494         sym++;
4495       else if (*sym == '@' && sym[2] == '.')
4496         sym += 3;
4497       else
4498         return sym;
4499     }
4500 }
4501
4502 /* Like rl78_strip_name_encoding, but does not strip leading asterisks.  This
4503    is important if the stripped name is going to be passed to assemble_name()
4504    as that handles asterisk prefixed names in a special manner.  */
4505
4506 static const char *
4507 rl78_strip_nonasm_name_encoding (const char * sym)
4508 {
4509   while (1)
4510     {
4511       if (*sym == '@' && sym[2] == '.')
4512         sym += 3;
4513       else
4514         return sym;
4515     }
4516 }
4517
4518
4519 static int
4520 rl78_attrlist_to_encoding (tree list, tree decl ATTRIBUTE_UNUSED)
4521 {
4522   while (list)
4523     {
4524       if (is_attribute_p ("saddr", TREE_PURPOSE (list)))
4525         return 's';
4526       list = TREE_CHAIN (list);
4527     }
4528
4529   return 0;
4530 }
4531
4532 #define RL78_ATTRIBUTES(decl)                           \
4533   (TYPE_P (decl)) ? TYPE_ATTRIBUTES (decl)              \
4534                 : DECL_ATTRIBUTES (decl)                \
4535                   ? (DECL_ATTRIBUTES (decl))            \
4536                   : TYPE_ATTRIBUTES (TREE_TYPE (decl))
4537
4538 #undef  TARGET_ENCODE_SECTION_INFO
4539 #define TARGET_ENCODE_SECTION_INFO rl78_encode_section_info
4540
4541 static void
4542 rl78_encode_section_info (tree decl, rtx rtl, int first)
4543 {
4544   rtx rtlname;
4545   const char * oldname;
4546   char encoding;
4547   char * newname;
4548   tree idp;
4549   tree type;
4550   tree rl78_attributes;
4551
4552   if (!first)
4553     return;
4554
4555   rtlname = XEXP (rtl, 0);
4556
4557   if (GET_CODE (rtlname) == SYMBOL_REF)
4558     oldname = XSTR (rtlname, 0);
4559   else if (GET_CODE (rtlname) == MEM
4560            && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
4561     oldname = XSTR (XEXP (rtlname, 0), 0);
4562   else
4563     gcc_unreachable ();
4564
4565   type = TREE_TYPE (decl);
4566   if (type == error_mark_node)
4567     return;
4568   if (! DECL_P (decl))
4569     return;
4570   rl78_attributes = RL78_ATTRIBUTES (decl);
4571
4572   encoding = rl78_attrlist_to_encoding (rl78_attributes, decl);
4573
4574   if (encoding)
4575     {
4576       newname = (char *) alloca (strlen (oldname) + 4);
4577       sprintf (newname, "@%c.%s", encoding, oldname);
4578       idp = get_identifier (newname);
4579       XEXP (rtl, 0) =
4580         gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
4581       SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl);
4582       SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl);
4583     }
4584 }
4585
4586 #undef  TARGET_ASM_INIT_SECTIONS
4587 #define TARGET_ASM_INIT_SECTIONS        rl78_asm_init_sections
4588
4589 static void
4590 rl78_asm_init_sections (void)
4591 {
4592   saddr_section
4593     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
4594                            "\t.section .saddr,\"aw\",@progbits");
4595   frodata_section
4596     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
4597                            "\t.section .frodata,\"aw\",@progbits");
4598 }
4599
4600 #undef  TARGET_ASM_SELECT_SECTION
4601 #define TARGET_ASM_SELECT_SECTION       rl78_select_section
4602
4603 static section *
4604 rl78_select_section (tree decl,
4605                      int reloc,
4606                      unsigned HOST_WIDE_INT align)
4607 {
4608   int readonly = 1;
4609
4610   switch (TREE_CODE (decl))
4611     {
4612     case VAR_DECL:
4613       if (!TREE_READONLY (decl)
4614           || TREE_SIDE_EFFECTS (decl)
4615           || !DECL_INITIAL (decl)
4616           || (DECL_INITIAL (decl) != error_mark_node
4617               && !TREE_CONSTANT (DECL_INITIAL (decl))))
4618         readonly = 0;
4619       break;
4620     case CONSTRUCTOR:
4621       if (! TREE_CONSTANT (decl))
4622         readonly = 0;
4623       break;
4624
4625     default:
4626       break;
4627     }
4628
4629   if (TREE_CODE (decl) == VAR_DECL)
4630     {
4631       const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
4632
4633       if (name[0] == '@' && name[2] == '.')
4634         switch (name[1])
4635           {
4636           case 's':
4637             return saddr_section;
4638           }
4639
4640       if (TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_FAR
4641           && readonly)
4642         {
4643           return frodata_section;
4644         }
4645     }
4646
4647   if (readonly)
4648     return TARGET_ES0 ? frodata_section : readonly_data_section;
4649
4650   switch (categorize_decl_for_section (decl, reloc))
4651     {
4652     case SECCAT_TEXT:   return text_section;
4653     case SECCAT_DATA:   return data_section;
4654     case SECCAT_BSS:    return bss_section;
4655     case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
4656     default:
4657       return default_select_section (decl, reloc, align);
4658     }
4659 }
4660
4661 void
4662 rl78_output_labelref (FILE *file, const char *str)
4663 {
4664   const char *str2;
4665
4666   str2 = targetm.strip_name_encoding (str);
4667   if (str2[0] != '.')
4668     fputs (user_label_prefix, file);
4669   fputs (str2, file);
4670 }
4671
4672 void
4673 rl78_output_aligned_common (FILE *stream,
4674                             tree decl ATTRIBUTE_UNUSED,
4675                             const char *name,
4676                             int size, int align, int global)
4677 {
4678   /* We intentionally don't use rl78_section_tag() here.  */
4679   if (name[0] == '@' && name[2] == '.')
4680     {
4681       const char *sec = 0;
4682       switch (name[1])
4683         {
4684         case 's':
4685           switch_to_section (saddr_section);
4686           sec = ".saddr";
4687           break;
4688         }
4689       if (sec)
4690         {
4691           const char *name2;
4692           int p2align = 0;
4693
4694           while (align > BITS_PER_UNIT)
4695             {
4696               align /= 2;
4697               p2align ++;
4698             }
4699           name2 = targetm.strip_name_encoding (name);
4700           if (global)
4701             fprintf (stream, "\t.global\t_%s\n", name2);
4702           fprintf (stream, "\t.p2align %d\n", p2align);
4703           fprintf (stream, "\t.type\t_%s,@object\n", name2);
4704           fprintf (stream, "\t.size\t_%s,%d\n", name2, size);
4705           fprintf (stream, "_%s:\n\t.zero\t%d\n", name2, size);
4706           return;
4707         }
4708     }
4709
4710   if (!global)
4711     {
4712       fprintf (stream, "\t.local\t");
4713       assemble_name (stream, name);
4714       fprintf (stream, "\n");
4715     }
4716   fprintf (stream, "\t.comm\t");
4717   assemble_name (stream, name);
4718   fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT);
4719 }
4720
4721 #undef  TARGET_INSERT_ATTRIBUTES
4722 #define TARGET_INSERT_ATTRIBUTES rl78_insert_attributes
4723
4724 static void
4725 rl78_insert_attributes (tree decl, tree *attributes ATTRIBUTE_UNUSED)
4726 {
4727   if (TARGET_ES0
4728       && TREE_CODE (decl) == VAR_DECL
4729       && TREE_READONLY (decl)
4730       && TREE_ADDRESSABLE (decl)
4731       && TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_GENERIC)
4732     {
4733       tree type = TREE_TYPE (decl);
4734       tree attr = TYPE_ATTRIBUTES (type);
4735       int q = TYPE_QUALS_NO_ADDR_SPACE (type) | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_FAR);
4736
4737       TREE_TYPE (decl) = build_type_attribute_qual_variant (type, attr, q);
4738     }
4739 }
4740
4741 #undef  TARGET_ASM_INTEGER
4742 #define TARGET_ASM_INTEGER rl78_asm_out_integer
4743
4744 static bool
4745 rl78_asm_out_integer (rtx x, unsigned int size, int aligned_p)
4746 {
4747   if (default_assemble_integer (x, size, aligned_p))
4748     return true;
4749
4750   if (size == 4)
4751     {
4752       assemble_integer_with_op (".long\t", x);
4753       return true;
4754     }
4755
4756   return false;
4757 }
4758 \f
4759 #undef  TARGET_UNWIND_WORD_MODE
4760 #define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode
4761
4762 static scalar_int_mode
4763 rl78_unwind_word_mode (void)
4764 {
4765   return HImode;
4766 }
4767
4768 #ifndef USE_COLLECT2
4769 #undef  TARGET_ASM_CONSTRUCTOR
4770 #define TARGET_ASM_CONSTRUCTOR rl78_asm_constructor
4771 #undef  TARGET_ASM_DESTRUCTOR
4772 #define TARGET_ASM_DESTRUCTOR  rl78_asm_destructor
4773
4774 static void
4775 rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
4776 {
4777   section *sec;
4778
4779   if (priority != DEFAULT_INIT_PRIORITY)
4780     {
4781       /* This section of the function is based upon code copied
4782          from: gcc/varasm.c:get_cdtor_priority_section().  */
4783       char buf[18];
4784
4785       sprintf (buf, "%s.%.5u", is_ctor ? ".ctors" : ".dtors",
4786                MAX_INIT_PRIORITY - priority);
4787       sec = get_section (buf, 0, NULL);
4788     }
4789   else
4790     sec = is_ctor ? ctors_section : dtors_section;
4791
4792   assemble_addr_to_section (symbol, sec);
4793 }
4794
4795 static void
4796 rl78_asm_constructor (rtx symbol, int priority)
4797 {
4798   rl78_asm_ctor_dtor (symbol, priority, true);
4799 }
4800
4801 static void
4802 rl78_asm_destructor (rtx symbol, int priority)
4803 {
4804   rl78_asm_ctor_dtor (symbol, priority, false);
4805 }
4806 #endif /* ! USE_COLLECT2 */
4807
4808 /* Scan backwards through the insn chain looking to see if the flags
4809    have been set for a comparison of OP against OPERAND.  Start with
4810    the insn *before* the current insn.  */
4811
4812 bool
4813 rl78_flags_already_set (rtx op, rtx operand)
4814 {
4815   /* We only track the Z flag.  */
4816   if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
4817     return false;
4818
4819   /* This should not happen, but let's be paranoid.  */
4820   if (current_output_insn == NULL_RTX)
4821     return false;
4822
4823   rtx_insn *insn;
4824   bool res = false;
4825
4826   for (insn = prev_nonnote_nondebug_insn (current_output_insn);
4827        insn != NULL_RTX;
4828        insn = prev_nonnote_nondebug_insn (insn))
4829     {
4830       if (LABEL_P (insn))
4831         break;
4832
4833       if (! INSN_P (insn))
4834         continue;
4835
4836       /* Make sure that the insn can be recognized.  */
4837       if (recog_memoized (insn) == -1)
4838         continue;
4839
4840       enum attr_update_Z updated = get_attr_update_Z (insn);
4841
4842       rtx set = single_set (insn);
4843       bool must_break = (set != NULL_RTX && rtx_equal_p (operand, SET_DEST (set)));
4844
4845       switch (updated)
4846         {
4847         case UPDATE_Z_NO:
4848           break;
4849         case UPDATE_Z_CLOBBER:
4850           must_break = true;
4851           break;
4852         case UPDATE_Z_UPDATE_Z:
4853           res = must_break;
4854           must_break = true;
4855           break;
4856         default:
4857           gcc_unreachable ();
4858         }
4859
4860       if (must_break)
4861         break;
4862     }
4863
4864   /* We have to re-recognize the current insn as the call(s) to
4865      get_attr_update_Z() above will have overwritten the recog_data cache.  */
4866   recog_memoized (current_output_insn);
4867   cleanup_subreg_operands (current_output_insn);
4868   constrain_operands_cached (current_output_insn, 1);
4869
4870   return res;
4871 }
4872
4873 const char *
4874 rl78_addsi3_internal (rtx * operands, unsigned int alternative)
4875 {
4876   const char *addH2 = "addw ax, %H2\n\t";
4877
4878   /* If we are adding in a constant symbolic address when -mes0
4879      is active then we know that the address must be <64K and
4880      that it is invalid to access anything above 64K relative to
4881      this address.  So we can skip adding in the high bytes.  */
4882   if (TARGET_ES0
4883       && GET_CODE (operands[2]) == SYMBOL_REF
4884       && TREE_CODE (SYMBOL_REF_DECL (operands[2])) == VAR_DECL
4885       && TREE_READONLY (SYMBOL_REF_DECL (operands[2]))
4886       && ! TREE_SIDE_EFFECTS (SYMBOL_REF_DECL (operands[2])))
4887     return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax";
4888
4889   if(CONST_INT_P(operands[2]))
4890   {
4891     if((INTVAL(operands[2]) & 0xFFFF0000) == 0)
4892     {
4893         addH2 = "";
4894     }
4895     else if((INTVAL(operands[2]) & 0xFFFF0000) == 0x00010000)
4896     {
4897         addH2 = "incw ax\n\t";
4898     }
4899     else if((INTVAL(operands[2]) & 0xFFFF0000) == 0xFFFF0000)
4900     {
4901         addH2 = "decw ax\n\t";
4902     }
4903   }
4904
4905   switch (alternative)
4906     {
4907     case 0:
4908     case 1:
4909           snprintf(fmt_buffer, sizeof(fmt_buffer),
4910                "movw ax, %%h1\n\taddw ax, %%h2\n\tmovw %%h0, ax\n\tmovw ax, %%H1\n\tsknc\n\tincw ax\n\t%smovw %%H0,ax", addH2);
4911           break;
4912     case 2:
4913           snprintf(fmt_buffer, sizeof(fmt_buffer),
4914                "movw ax, %%h1\n\taddw ax, %%h2\n\tmovw bc, ax\n\tmovw ax, %%H1\n\tsknc\n\tincw ax\n\t%smovw %%H0, ax\n\tmovw ax, bc\n\tmovw %%h0, ax", addH2);
4915           break;
4916     default:
4917       gcc_unreachable ();
4918     }
4919
4920   return fmt_buffer;
4921 }
4922
4923 rtx
4924 rl78_emit_libcall (const char *name, enum rtx_code code,
4925                    enum machine_mode dmode, enum machine_mode smode,
4926                    int noperands, rtx *operands)
4927 {
4928   rtx ret;
4929   rtx_insn *insns;
4930   rtx libcall;
4931   rtx equiv;
4932
4933   start_sequence ();
4934   libcall = gen_rtx_SYMBOL_REF (Pmode, name);
4935
4936   switch (noperands)
4937     {
4938     case 2:
4939       ret = emit_library_call_value (libcall, NULL_RTX, LCT_CONST,
4940                                      dmode, operands[1], smode);
4941       equiv = gen_rtx_fmt_e (code, dmode, operands[1]);
4942       break;
4943
4944     case 3:
4945       ret = emit_library_call_value (libcall, NULL_RTX,
4946                                      LCT_CONST, dmode,
4947                                      operands[1], smode, operands[2],
4948                                      smode);
4949       equiv = gen_rtx_fmt_ee (code, dmode, operands[1], operands[2]);
4950       break;
4951
4952     default:
4953       gcc_unreachable ();
4954     }
4955
4956   insns = get_insns ();
4957   end_sequence ();
4958   emit_libcall_block (insns, operands[0], ret, equiv);
4959   return ret;
4960 }
4961
4962 \f
4963 #undef  TARGET_PREFERRED_RELOAD_CLASS
4964 #define TARGET_PREFERRED_RELOAD_CLASS rl78_preferred_reload_class
4965
4966 static reg_class_t
4967 rl78_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
4968 {
4969   if (rclass == NO_REGS)
4970     rclass = V_REGS;
4971
4972   return rclass;
4973 }
4974
4975 \f
4976 struct gcc_target targetm = TARGET_INITIALIZER;
4977
4978 #include "gt-rl78.h"