OSDN Git Service

.
[pf3gnuchains/gcc-fork.git] / gcc / config / rl78 / rl78.c
1 /* Subroutines used for code generation on Renesas RL78 processors.
2    Copyright (C) 2011 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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "libfuncs.h"
38 #include "recog.h"
39 #include "diagnostic-core.h"
40 #include "toplev.h"
41 #include "reload.h"
42 #include "df.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "debug.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "langhooks.h"
49 #include "rl78-protos.h"
50 #include "tree-pass.h"
51 \f
52 static inline bool is_interrupt_func (const_tree decl);
53 static inline bool is_brk_interrupt_func (const_tree decl);
54 static void rl78_reorg (void);
55 \f
56
57 /* Debugging statements are tagged with DEBUG0 only so that they can
58    be easily enabled individually, by replacing the '0' with '1' as
59    needed.  */
60 #define DEBUG0 0
61 #define DEBUG1 1
62
63 /* REGISTER_NAMES has the names for individual 8-bit registers, but
64    these have the names we need to use when referring to 16-bit
65    register pairs.  */
66 static const char * const word_regnames[] =
67 {
68   "ax", "AX", "bc", "BC", "de", "DE", "hl", "HL",
69   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
70   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
71   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
72   "sp", "ap", "psw", "es", "cs"
73 };
74
75 struct GTY(()) machine_function
76 {
77   /* If set, the rest of the fields have been computed.  */
78   int computed;
79   /* Which register pairs need to be pushed in the prologue.  */
80   int need_to_push [FIRST_PSEUDO_REGISTER / 2];
81
82   /* These fields describe the frame layout...  */
83   /* arg pointer */
84   /* 4 bytes for saved PC */
85   int framesize_regs;
86   /* frame pointer */
87   int framesize_locals;
88   int framesize_outgoing;
89   /* stack pointer */
90   int framesize;
91
92   /* If set, recog is allowed to match against the "real" patterns.  */
93   int real_insns_ok;
94   /* If set, recog is allowed to match against the "virtual" patterns.  */
95   int virt_insns_ok;
96   /* Set if the current function needs to clean up any trampolines.  */
97   int trampolines_used;
98 };
99
100 /* This is our init_machine_status, as set in
101    rl78_option_override.  */
102 static struct machine_function *
103 rl78_init_machine_status (void)
104 {
105   struct machine_function *m;
106
107   m = ggc_alloc_cleared_machine_function ();
108   m->virt_insns_ok = 1;
109
110   return m;
111 }
112
113 /* Returns whether to run the devirtualization pass.  */
114 static bool
115 devirt_gate (void)
116 {
117   return true;
118 }
119
120 /* Runs the devirtualization pass.  */
121 static unsigned int
122 devirt_pass (void)
123 {
124   rl78_reorg ();
125   return 0;
126 }
127
128 /* This pass converts virtual instructions using virtual registers, to
129    real instructions using real registers.  Rather than run it as
130    reorg, we reschedule it before vartrack to help with debugging.  */
131 static struct opt_pass rl78_devirt_pass =
132 {
133   RTL_PASS,
134   "devirt",
135   devirt_gate,
136   devirt_pass,
137   NULL,
138   NULL,
139   212,
140   TV_MACH_DEP,
141   0, 0, 0,
142   0,
143   TODO_dump_func
144 };
145
146 static struct register_pass_info rl78_devirt_info =
147 {
148   & rl78_devirt_pass,
149   "vartrack",
150   1,
151   PASS_POS_INSERT_BEFORE
152 };
153
154 #undef  TARGET_ASM_FILE_START
155 #define TARGET_ASM_FILE_START rl78_asm_file_start
156
157 static void
158 rl78_asm_file_start (void)
159 {
160   int i;
161
162   for (i = 0; i < 8; i++)
163     {
164       fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i);
165       fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i);
166     }
167
168   register_pass (& rl78_devirt_info);
169 }
170
171 \f
172 #undef  TARGET_OPTION_OVERRIDE
173 #define TARGET_OPTION_OVERRIDE          rl78_option_override
174
175 static void
176 rl78_option_override (void)
177 {
178   flag_omit_frame_pointer = 1;
179   flag_no_function_cse = 1;
180   flag_split_wide_types = 0;
181
182   init_machine_status = rl78_init_machine_status;
183 }
184
185 /* Most registers are 8 bits.  Some are 16 bits because, for example,
186    gcc doesn't like dealing with $FP as a register pair.  This table
187    maps register numbers to size in bytes.  */
188 static const int register_sizes[] =
189 {
190   1, 1, 1, 1, 1, 1, 1, 1,
191   1, 1, 1, 1, 1, 1, 1, 1,
192   1, 1, 1, 1, 1, 1, 2, 1,
193   1, 1, 1, 1, 1, 1, 1, 1,
194   2, 2, 1, 1, 1
195 };
196
197 /* Predicates used in the MD patterns.  This one is true when virtual
198    insns may be matched, which typically means before (or during) the
199    devirt pass.  */
200 bool
201 rl78_virt_insns_ok (void)
202 {
203   if (cfun)
204     return cfun->machine->virt_insns_ok;
205   return true;
206 }
207
208 /* Predicates used in the MD patterns.  This one is true when real
209    insns may be matched, which typically means after (or during) the
210    devirt pass.  */
211 bool
212 rl78_real_insns_ok (void)
213 {
214   if (cfun)
215     return cfun->machine->real_insns_ok;
216   return false;
217 }
218
219 /* Implements HARD_REGNO_NREGS.  */
220 int
221 rl78_hard_regno_nregs (int regno, enum machine_mode mode)
222 {
223   int rs = register_sizes[regno];
224   if (rs < 1)
225     rs = 1;
226   return ((GET_MODE_SIZE (mode) + rs - 1) / rs);
227 }
228
229 /* Implements HARD_REGNO_MODE_OK.  */
230 int
231 rl78_hard_regno_mode_ok (int regno, enum machine_mode mode)
232 {
233   int s = GET_MODE_SIZE (mode);
234
235   if (s < 1)
236     return 0;
237   /* These are not to be used by gcc.  */
238   if (regno == 23 || regno == ES_REG || regno == CS_REG)
239     return 0;
240   /* $fp can alway sbe accessed as a 16-bit value.  */
241   if (regno == FP_REG && s == 2)
242     return 1;
243   if (regno < SP_REG)
244     {
245       /* Since a reg-reg move is really a reg-mem move, we must
246          enforce alignment.  */
247       if (s > 1 && (regno % 2))
248         return 0;
249       return 1;
250     }
251   if (s == CC_REGNUM)
252     return (mode == BImode);
253   /* All other registers must be accessed in their natural sizes.  */
254   if (s == register_sizes [regno])
255     return 1;
256   return 0;
257 }
258
259 /* Simplify_gen_subreg() doesn't handle memory references the way we
260    need it to below, so we use this function for when we must get a
261    valid subreg in a "natural" state.  */
262 static rtx
263 rl78_subreg (enum machine_mode mode, rtx r, enum machine_mode omode, int byte)
264 {
265   if (GET_CODE (r) == MEM)
266     return adjust_address (r, mode, byte);
267   else
268     return simplify_gen_subreg (mode, r, omode, byte);
269 }
270
271 /* Used by movsi.  Split SImode moves into two HImode moves, using
272    appropriate patterns for the upper and lower halves of symbols.  */
273 void
274 rl78_expand_movsi (rtx *operands)
275 {
276   rtx op00, op02, op10, op12;
277
278   op00 = rl78_subreg (HImode, operands[0], SImode, 0);
279   op02 = rl78_subreg (HImode, operands[0], SImode, 2);
280   if (GET_CODE (operands[1]) == CONST
281       || GET_CODE (operands[1]) == SYMBOL_REF)
282     {
283       op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
284       op10 = gen_rtx_CONST (HImode, op10);
285       op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
286       op12 = gen_rtx_CONST (HImode, op12);
287     }
288   else
289     {
290       op10 = rl78_subreg (HImode, operands[1], SImode, 0);
291       op12 = rl78_subreg (HImode, operands[1], SImode, 2);
292     }
293
294   if (rtx_equal_p (operands[0], operands[1]))
295     ;
296   else if (rtx_equal_p (op00, op12))
297     {
298       emit_move_insn (op02, op12);
299       emit_move_insn (op00, op10);
300     }
301   else
302     {
303       emit_move_insn (op00, op10);
304       emit_move_insn (op02, op12);
305     }
306 }
307
308 /* Used by various two-operand expanders which cannot accept all
309    operands in the "far" namespace.  Force some such operands into
310    registers so that each pattern has at most one far operand.  */
311 int
312 rl78_force_nonfar_2 (rtx *operands, rtx (*gen)(rtx,rtx))
313 {
314   int did = 0;
315   rtx temp_reg = NULL;
316
317   /* FIXME: in the future, be smarter about only doing this if the
318      other operand is also far, assuming the devirtualizer can also
319      handle that.  */
320   if (rl78_far_p (operands[0]))
321     {
322       temp_reg = operands[0];
323       operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
324       did = 1;
325     }
326   if (!did)
327     return 0;
328
329   emit_insn (gen (operands[0], operands[1]));
330   if (temp_reg)
331     emit_move_insn (temp_reg, operands[0]);
332   return 1;
333 }
334
335 /* Likewise, but for three-operand expanders.  */
336 int
337 rl78_force_nonfar_3 (rtx *operands, rtx (*gen)(rtx,rtx,rtx))
338 {
339   int did = 0;
340   rtx temp_reg = NULL;
341
342   /* FIXME: Likewise.  */
343   if (rl78_far_p (operands[1]))
344     {
345       rtx temp_reg = gen_reg_rtx (GET_MODE (operands[1]));
346       emit_move_insn (temp_reg, operands[1]);
347       operands[1] = temp_reg;
348       did = 1;
349     }
350   if (rl78_far_p (operands[0]))
351     {
352       temp_reg = operands[0];
353       operands[0] = gen_reg_rtx (GET_MODE (operands[0]));
354       did = 1;
355     }
356   if (!did)
357     return 0;
358
359   emit_insn (gen (operands[0], operands[1], operands[2]));
360   if (temp_reg)
361     emit_move_insn (temp_reg, operands[0]);
362   return 1;
363 }
364
365 #undef  TARGET_CAN_ELIMINATE
366 #define TARGET_CAN_ELIMINATE            rl78_can_eliminate
367
368 static bool
369 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUSED)
370 {
371   return true;
372 }
373
374 /* Returns nonzero if the given register needs to be saved by the
375    current function.  */
376 static int
377 need_to_save (int regno)
378 {
379   if (is_interrupt_func (cfun->decl))
380     {
381       if (regno < 8)
382         return 1; /* don't know what devirt will need */
383       if (regno > 23)
384         return 0; /* don't need to save interrupt registers */
385       if (current_function_is_leaf)
386         {
387           return df_regs_ever_live_p (regno);
388         }
389       else
390         return 1;
391     }
392   if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
393     return 1;
394   if (fixed_regs[regno])
395     return 0;
396   if (crtl->calls_eh_return)
397     return 1;
398   if (df_regs_ever_live_p (regno)
399       && !call_used_regs[regno])
400     return 1;
401   return 0;
402 }
403
404 /* We use this to wrap all emitted insns in the prologue.  */
405 static rtx
406 F (rtx x)
407 {
408   RTX_FRAME_RELATED_P (x) = 1;
409   return x;
410 }
411
412 /* Compute all the frame-related fields in our machine_function
413    structure.  */
414 static void
415 rl78_compute_frame_info (void)
416 {
417   int i;
418
419   cfun->machine->computed = 1;
420   cfun->machine->framesize_regs = 0;
421   cfun->machine->framesize_locals = get_frame_size ();
422   cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
423
424   for (i = 0; i < 16; i ++)
425     if (need_to_save (i * 2) || need_to_save (i * 2 + 1))
426       {
427         cfun->machine->need_to_push [i] = 1;
428         cfun->machine->framesize_regs += 2;
429       }
430     else
431       cfun->machine->need_to_push [i] = 0;
432
433   if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
434     cfun->machine->framesize_locals ++;
435
436   cfun->machine->framesize = (cfun->machine->framesize_regs
437                               + cfun->machine->framesize_locals
438                               + cfun->machine->framesize_outgoing);
439 }
440 \f
441 /* Returns true if the provided function has the specified attribute.  */
442 static inline bool
443 has_func_attr (const_tree decl, const char * func_attr)
444 {
445   if (decl == NULL_TREE)
446     decl = current_function_decl;
447
448   return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
449 }
450
451 /* Returns true if the provided function has the "interrupt" attribute.  */
452 static inline bool
453 is_interrupt_func (const_tree decl)
454 {
455   return has_func_attr (decl, "interrupt") || has_func_attr (decl, "brk_interrupt");
456 }
457
458 /* Returns true if the provided function has the "brk_interrupt" attribute.  */
459 static inline bool
460 is_brk_interrupt_func (const_tree decl)
461 {
462   return has_func_attr (decl, "brk_interrupt");
463 }
464
465 /* Check "interrupt" attributes.  */
466 static tree
467 rl78_handle_func_attribute (tree * node,
468                           tree   name,
469                           tree   args,
470                           int    flags ATTRIBUTE_UNUSED,
471                           bool * no_add_attrs)
472 {
473   gcc_assert (DECL_P (* node));
474   gcc_assert (args == NULL_TREE);
475
476   if (TREE_CODE (* node) != FUNCTION_DECL)
477     {
478       warning (OPT_Wattributes, "%qE attribute only applies to functions",
479                name);
480       * no_add_attrs = true;
481     }
482
483   /* FIXME: We ought to check that the interrupt and exception
484      handler attributes have been applied to void functions.  */
485   return NULL_TREE;
486 }
487
488 #undef  TARGET_ATTRIBUTE_TABLE
489 #define TARGET_ATTRIBUTE_TABLE          rl78_attribute_table
490
491 /* Table of RL78-specific attributes.  */
492 const struct attribute_spec rl78_attribute_table[] =
493 {
494   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
495      affects_type_identity.  */
496   { "interrupt",      0, 0, true, false, false, rl78_handle_func_attribute,
497     false },
498   { "brk_interrupt",  0, 0, true, false, false, rl78_handle_func_attribute,
499     false },
500   { NULL,             0, 0, false, false, false, NULL, false }
501 };
502
503
504 \f
505 /* Break down an address RTX into its component base/index/addend
506    portions and return TRUE if the address is of a valid form, else
507    FALSE.  */
508 static bool
509 characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
510 {
511   *base = NULL_RTX;
512   *index = NULL_RTX;
513   *addend = NULL_RTX;
514
515   if (GET_CODE (x) == REG)
516     {
517       *base = x;
518       return true;
519     }
520
521   /* We sometimes get these without the CONST wrapper */
522   if (GET_CODE (x) == PLUS
523       && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
524       && GET_CODE (XEXP (x, 1)) == CONST_INT)
525     {
526       *addend = x;
527       return true;
528     }
529
530   if (GET_CODE (x) == PLUS)
531     {
532       *base = XEXP (x, 0);
533       x = XEXP (x, 1);
534
535       if (GET_CODE (*base) != REG
536           && GET_CODE (x) == REG)
537         {
538           rtx tmp = *base;
539           *base = x;
540           x = tmp;
541         }
542
543       if (GET_CODE (*base) != REG)
544         return false;
545
546       if (GET_CODE (x) == ZERO_EXTEND
547           && GET_CODE (XEXP (x, 0)) == REG)
548         {
549           *index = XEXP (x, 0);
550           return false;
551         }
552     }
553
554   switch (GET_CODE (x))
555     {
556     case PLUS:
557       if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
558           && GET_CODE (XEXP (x, 0)) == CONST_INT)
559         {
560           *addend = x;
561           return true;
562         }
563       /* fall through */
564     case MEM:
565     case REG:
566       return false;
567
568     case CONST:
569     case SYMBOL_REF:
570     case CONST_INT:
571       *addend = x;
572       return true;
573
574     default:
575       return false;
576     }
577
578   return false;
579 }
580
581 /* Used by the Whb constraint.  Match addresses that use HL+B or HL+C
582    addressing.  */
583 bool
584 rl78_hl_b_c_addr_p (rtx op)
585 {
586   rtx hl, bc;
587
588   if (GET_CODE (op) != PLUS)
589     return false;
590   hl = XEXP (op, 0);
591   bc = XEXP (op, 1);
592   if (GET_CODE (hl) == ZERO_EXTEND)
593     {
594       rtx tmp = hl;
595       hl = bc;
596       bc = tmp;
597     }
598   if (GET_CODE (hl) != REG)
599     return false;
600   if (GET_CODE (bc) != ZERO_EXTEND)
601     return false;
602   bc = XEXP (bc, 0);
603   if (GET_CODE (bc) != REG)
604     return false;
605   if (REGNO (hl) != HL_REG)
606     return false;
607   if (REGNO (bc) != B_REG && REGNO (bc) != C_REG)
608     return false;
609
610   return true;
611 }
612
613 #define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
614
615 /* Used in various constraints and predicates to match operands in the
616    "far" address space.  */
617 int
618 rl78_far_p (rtx x)
619 {
620   if (GET_CODE (x) != MEM)
621     return 0;
622 #if DEBUG0
623   fprintf(stderr, "\033[35mrl78_far_p: "); debug_rtx(x);
624   fprintf(stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
625 #endif
626   return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
627 }
628
629 /* Return the appropriate mode for a named address pointer.  */
630 #undef TARGET_ADDR_SPACE_POINTER_MODE
631 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
632 static enum machine_mode
633 rl78_addr_space_pointer_mode (addr_space_t addrspace)
634 {
635   switch (addrspace)
636     {
637     case ADDR_SPACE_GENERIC:
638       return HImode;
639     case ADDR_SPACE_FAR:
640       return SImode;
641     default:
642       gcc_unreachable ();
643     }
644 }
645
646 /* Return the appropriate mode for a named address address.  */
647 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
648 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
649 static enum machine_mode
650 rl78_addr_space_address_mode (addr_space_t addrspace)
651 {
652   switch (addrspace)
653     {
654     case ADDR_SPACE_GENERIC:
655       return HImode;
656     case ADDR_SPACE_FAR:
657       return SImode;
658     default:
659       gcc_unreachable ();
660     }
661 }
662
663 #undef  TARGET_LEGITIMATE_CONSTANT_P
664 #define TARGET_LEGITIMATE_CONSTANT_P            rl78_is_legitimate_constant
665
666 static bool
667 rl78_is_legitimate_constant (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED)
668 {
669   return true;
670 }
671
672 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
673 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P  rl78_as_legitimate_address
674
675 bool
676 rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x,
677                             bool strict ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED)
678 {
679   rtx base, index, addend;
680
681   if (as == ADDR_SPACE_GENERIC
682       && GET_MODE (x) == SImode)
683     return false;
684
685   if (! characterize_address (x, &base, &index, &addend))
686     return false;
687
688   if (base && index)
689     {
690       int ir = REGNO (index);
691       int br = REGNO (base);
692
693 #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
694       OK (REG_IS (br, HL_REG) && REG_IS (ir, B_REG), "[hl+b]");
695       OK (REG_IS (br, HL_REG) && REG_IS (ir, C_REG), "[hl+c]");
696       return false;
697     }
698
699   if (strict && base && GET_CODE (base) == REG && REGNO (base) >= FIRST_PSEUDO_REGISTER)
700     return false;
701
702   return true;
703 }
704
705 /* Determine if one named address space is a subset of another.  */
706 #undef  TARGET_ADDR_SPACE_SUBSET_P
707 #define TARGET_ADDR_SPACE_SUBSET_P rl78_addr_space_subset_p
708 static bool
709 rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
710 {
711   gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_FAR);
712   gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_FAR);
713
714   if (subset == superset)
715     return true;
716
717   else
718     return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_FAR);
719 }
720
721 #undef  TARGET_ADDR_SPACE_CONVERT
722 #define TARGET_ADDR_SPACE_CONVERT rl78_addr_space_convert
723 /* Convert from one address space to another.  */
724 static rtx
725 rl78_addr_space_convert (rtx op, tree from_type, tree to_type)
726 {
727   addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
728   addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
729   rtx result;
730
731   gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_FAR);
732   gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_FAR);
733
734   if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_FAR)
735     {
736       /* This is unpredictable, as we're truncating off usable address
737          bits.  */
738
739       result = gen_reg_rtx (HImode);
740       emit_move_insn (result, simplify_subreg (HImode, op, SImode, 0));
741       return result;
742     }
743   else if (to_as == ADDR_SPACE_FAR && from_as == ADDR_SPACE_GENERIC)
744     {
745       /* This always works.  */
746       result = gen_reg_rtx (SImode);
747       debug_rtx(result);
748       debug_rtx(op);
749       emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op);
750       emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx);
751       return result;
752     }
753   else
754     gcc_unreachable ();
755 }
756
757 /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P.  */
758 bool
759 rl78_regno_mode_code_ok_for_base_p (int regno, enum machine_mode mode ATTRIBUTE_UNUSED,
760                                     addr_space_t address_space ATTRIBUTE_UNUSED,
761                                     int outer_code ATTRIBUTE_UNUSED, int index_code)
762 {
763   if (regno < 24 && regno >= 16)
764     return true;
765   if (index_code == REG)
766     return (regno == HL_REG);
767   if (regno == C_REG || regno == B_REG || regno == E_REG || regno == L_REG)
768     return true;
769   return false;
770 }
771
772 /* Implements MODE_CODE_BASE_REG_CLASS.  */
773 enum reg_class
774 rl78_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
775                                addr_space_t address_space ATTRIBUTE_UNUSED,
776                                int outer_code ATTRIBUTE_UNUSED,
777                                int index_code ATTRIBUTE_UNUSED)
778 {
779   return V_REGS;
780 }
781
782 /* Implements INITIAL_ELIMINATION_OFFSET.  The frame layout is
783    described in the machine_Function struct definition, above.  */
784 int
785 rl78_initial_elimination_offset (int from, int to)
786 {
787   int rv = 0; /* as if arg to arg */
788
789   rl78_compute_frame_info ();
790
791   switch (to)
792     {
793     case STACK_POINTER_REGNUM:
794       rv += cfun->machine->framesize_outgoing;
795       rv += cfun->machine->framesize_locals;
796       /* Fall through.  */
797     case FRAME_POINTER_REGNUM:
798       rv += cfun->machine->framesize_regs;
799       rv += 4;
800       break;
801     default:
802       gcc_unreachable ();
803     }
804
805   switch (from)
806     {
807     case FRAME_POINTER_REGNUM:
808       rv -= 4;
809       rv -= cfun->machine->framesize_regs;
810     case ARG_POINTER_REGNUM:
811       break;
812     default:
813       gcc_unreachable ();
814     }
815
816   return rv;
817 }
818
819 /* Expand the function prologue (from the prologue pattern).  */
820 void
821 rl78_expand_prologue (void)
822 {
823   int i, fs;
824   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
825   int rb = 0;
826
827   if (!cfun->machine->computed)
828     rl78_compute_frame_info ();
829
830   for (i = 0; i < 16; i++)
831     if (cfun->machine->need_to_push [i])
832       {
833         int need_bank = i/4;
834         if (need_bank != rb)
835           {
836             emit_insn (gen_sel_rb (GEN_INT (need_bank)));
837             rb = need_bank;
838           }
839         F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2))));
840       }
841   if (rb != 0)
842     emit_insn (gen_sel_rb (GEN_INT (0)));
843
844   if (frame_pointer_needed)
845     F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM),
846                        gen_rtx_REG (HImode, STACK_POINTER_REGNUM)));
847
848   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
849   while (fs > 0)
850     {
851       int fs_byte = (fs > 254) ? 254 : fs;
852       F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte))));
853       fs -= fs_byte;
854     }
855 }
856
857 /* Expand the function epilogue (from the epilogue pattern).  */
858 void
859 rl78_expand_epilogue (void)
860 {
861   int i, fs;
862   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
863   int rb = 0;
864
865   if (frame_pointer_needed)
866     {
867       emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM),
868                       gen_rtx_REG (HImode, FRAME_POINTER_REGNUM));
869     }
870   else
871     {
872       fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
873       while (fs > 0)
874         {
875           int fs_byte = (fs > 254) ? 254 : fs;
876
877           emit_insn (gen_addhi3 (sp, sp, GEN_INT (fs_byte)));
878           fs -= fs_byte;
879         }
880     }
881
882   for (i = 15; i >= 0; i--)
883     if (cfun->machine->need_to_push [i])
884       {
885         int need_bank = i / 4;
886
887         if (need_bank != rb)
888           {
889             emit_insn (gen_sel_rb (GEN_INT (need_bank)));
890             rb = need_bank;
891           }
892         emit_insn (gen_pop (gen_rtx_REG (HImode, i * 2)));
893       }
894
895   if (rb != 0)
896     emit_insn (gen_sel_rb (GEN_INT (0)));
897
898   if (cfun->machine->trampolines_used)
899     emit_insn (gen_trampoline_uninit ());
900
901   if (is_brk_interrupt_func (cfun->decl))
902     emit_jump_insn (gen_brk_interrupt_return ());
903   else if (is_interrupt_func (cfun->decl))
904     emit_jump_insn (gen_interrupt_return ());
905   else
906     emit_jump_insn (gen_return ());
907 }
908
909 /* Likewise, for exception handlers.  */
910 void
911 rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED)
912 {
913   /* FIXME - replace this with an indirect jump with stack adjust.  */
914   emit_jump_insn (gen_return ());
915 }
916
917 #undef  TARGET_ASM_FUNCTION_PROLOGUE
918 #define TARGET_ASM_FUNCTION_PROLOGUE    rl78_start_function
919
920 /* We don't use this to actually emit the function prologue.  We use
921    this to insert a comment in the asm file describing the
922    function.  */
923 static void
924 rl78_start_function (FILE *file, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
925 {
926   int i;
927
928   if (cfun->machine->framesize == 0)
929     return;
930   fprintf (file, "\t; start of function\n");
931
932   if (cfun->machine->framesize_regs)
933     {
934       fprintf (file, "\t; push %d:", cfun->machine->framesize_regs);
935       for (i = 0; i < 16; i ++)
936         if (cfun->machine->need_to_push[i])
937           fprintf (file, " %s", word_regnames[i*2]);
938       fprintf(file, "\n");
939     }
940
941   if (frame_pointer_needed)
942     fprintf (file, "\t; $fp points here (r22)\n");
943
944   if (cfun->machine->framesize_locals)
945     fprintf (file, "\t; locals: %d byte%s\n", cfun->machine->framesize_locals,
946              cfun->machine->framesize_locals == 1 ? "" : "s");
947
948   if (cfun->machine->framesize_outgoing)
949     fprintf (file, "\t; outgoing: %d byte%s\n", cfun->machine->framesize_outgoing,
950              cfun->machine->framesize_outgoing == 1 ? "" : "s");
951 }
952
953 /* Return an RTL describing where a function return value of type RET_TYPE
954    is held.  */
955
956 #undef  TARGET_FUNCTION_VALUE
957 #define TARGET_FUNCTION_VALUE           rl78_function_value
958
959 static rtx
960 rl78_function_value (const_tree ret_type,
961                      const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
962                      bool       outgoing ATTRIBUTE_UNUSED)
963 {
964   enum machine_mode mode = TYPE_MODE (ret_type);
965
966   return gen_rtx_REG (mode, 8);
967 }
968
969 #undef  TARGET_PROMOTE_FUNCTION_MODE
970 #define TARGET_PROMOTE_FUNCTION_MODE rl78_promote_function_mode
971
972 static enum machine_mode
973 rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
974                             enum machine_mode mode,
975                             int *punsignedp ATTRIBUTE_UNUSED,
976                             const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED)
977 {
978   return mode;
979 }
980
981 /* Return an RTL expression describing the register holding a function
982    parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
983    be passed on the stack.  CUM describes the previous parameters to the
984    function and NAMED is false if the parameter is part of a variable
985    parameter list, or the last named parameter before the start of a
986    variable parameter list.  */
987
988 #undef  TARGET_FUNCTION_ARG
989 #define TARGET_FUNCTION_ARG             rl78_function_arg
990
991 static rtx
992 rl78_function_arg (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
993                    enum machine_mode mode ATTRIBUTE_UNUSED,
994                    const_tree type ATTRIBUTE_UNUSED,
995                    bool named ATTRIBUTE_UNUSED)
996 {
997   return NULL_RTX;
998 }
999
1000 #undef  TARGET_FUNCTION_ARG_ADVANCE
1001 #define TARGET_FUNCTION_ARG_ADVANCE     rl78_function_arg_advance
1002
1003 static void
1004 rl78_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type,
1005                            bool named ATTRIBUTE_UNUSED)
1006 {
1007   int rounded_size;
1008   CUMULATIVE_ARGS * cum = get_cumulative_args (cum_v);
1009
1010   rounded_size = ((mode == BLKmode)
1011                   ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
1012   if (rounded_size & 1)
1013     rounded_size ++;
1014   (*cum) += rounded_size;
1015 }
1016
1017 #undef  TARGET_FUNCTION_ARG_BOUNDARY
1018 #define TARGET_FUNCTION_ARG_BOUNDARY rl78_function_arg_boundary
1019
1020 static unsigned int
1021 rl78_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
1022                             const_tree type ATTRIBUTE_UNUSED)
1023 {
1024   return 16;
1025 }
1026
1027 /* Supported modifier letters:
1028
1029    A - address of a MEM
1030    S - SADDR form of a real register
1031    v - real register corresponding to a virtual register
1032    m - minus - negative of CONST_INT value.
1033    c - inverse of a conditional (NE vs EQ for example)
1034
1035    h - bottom HI of an SI
1036    H - top HI of an SI
1037    q - bottom QI of an HI
1038    Q - top QI of an HI
1039    e - third QI of an SI (i.e. where the ES register gets values from)
1040
1041 */
1042
1043 /* Implements the bulk of rl78_print_operand, below.  We do it this
1044    way because we need to test for a constant at the top level and
1045    insert the '#', but not test for it anywhere else as we recurse
1046    down into the operand.  */
1047 static void
1048 rl78_print_operand_1 (FILE * file, rtx op, int letter)
1049 {
1050   int need_paren;
1051
1052   switch (GET_CODE (op))
1053     {
1054     case MEM:
1055       if (letter == 'A')
1056         rl78_print_operand_1 (file, XEXP (op, 0), letter);
1057       else
1058         {
1059           if (rl78_far_p (op))
1060             fprintf(file, "es:");
1061           if (letter == 'H')
1062             {
1063               op = adjust_address (op, HImode, 2);
1064               letter = 0;
1065             }
1066           if (letter == 'h')
1067             {
1068               op = adjust_address (op, HImode, 0);
1069               letter = 0;
1070             }
1071           if (letter == 'Q')
1072             {
1073               op = adjust_address (op, QImode, 1);
1074               letter = 0;
1075             }
1076           if (letter == 'q')
1077             {
1078               op = adjust_address (op, QImode, 0);
1079               letter = 0;
1080             }
1081           if (letter == 'e')
1082             {
1083               op = adjust_address (op, QImode, 2);
1084               letter = 0;
1085             }
1086           if (CONSTANT_P (XEXP (op, 0)))
1087             {
1088               fprintf(file, "!");
1089               rl78_print_operand_1 (file, XEXP (op, 0), letter);
1090             }
1091           else if (GET_CODE (XEXP (op, 0)) == PLUS
1092                    && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF)
1093             {
1094               fprintf(file, "!");
1095               rl78_print_operand_1 (file, XEXP (op, 0), letter);
1096             }
1097           else if (GET_CODE (XEXP (op, 0)) == PLUS
1098                    && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
1099                    && REGNO (XEXP (XEXP (op, 0), 0)) == 2)
1100             {
1101               rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u');
1102               fprintf(file, "[");
1103               rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0);
1104               fprintf(file, "]");
1105             }
1106           else
1107             {
1108               fprintf(file, "[");
1109               rl78_print_operand_1 (file, XEXP (op, 0), letter);
1110               fprintf(file, "]");
1111             }
1112         }
1113       break;
1114
1115     case REG:
1116       if (letter == 'Q')
1117         fprintf (file, "%s", reg_names [REGNO (op) | 1]);
1118       else if (letter == 'H')
1119         fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1120       else if (letter == 'q')
1121         fprintf (file, "%s", reg_names [REGNO (op) & ~1]);
1122       else if (letter == 'e')
1123         fprintf (file, "%s", reg_names [REGNO (op) + 2]);
1124       else if (letter == 'S')
1125         fprintf (file, "0x%x", 0xffef8 + REGNO (op));
1126       else if (GET_MODE (op) == HImode
1127                && ! (REGNO (op) & ~0xfe))
1128         {
1129           if (letter == 'v')
1130             fprintf (file, "%s", word_regnames [REGNO (op) % 8]);
1131           else
1132             fprintf (file, "%s", word_regnames [REGNO (op)]);
1133         }
1134       else
1135         fprintf (file, "%s", reg_names [REGNO (op)]);
1136       break;
1137
1138     case CONST_INT:
1139       if (letter == 'Q')
1140         fprintf (file, "%ld", INTVAL (op) >> 8);
1141       else if (letter == 'H')
1142         fprintf (file, "%ld", INTVAL (op) >> 16);
1143       else if (letter == 'q')
1144         fprintf (file, "%ld", INTVAL (op) & 0xff);
1145       else if (letter == 'h')
1146         fprintf (file, "%ld", INTVAL (op) & 0xffff);
1147       else if (letter == 'e')
1148         fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
1149       else if (letter == 'm')
1150         fprintf (file, "%ld", - INTVAL (op));
1151       else
1152         fprintf(file, "%ld", INTVAL (op));
1153       break;
1154
1155     case CONST:
1156       rl78_print_operand_1 (file, XEXP (op, 0), letter);
1157       break;
1158
1159     case ZERO_EXTRACT:
1160       {
1161         int bits = INTVAL (XEXP (op, 1));
1162         int ofs = INTVAL (XEXP (op, 2));
1163         if (bits == 16 && ofs == 0)
1164           fprintf (file, "%%lo16(");
1165         else if (bits == 16 && ofs == 16)
1166           fprintf (file, "%%hi16(");
1167         else if (bits == 8 && ofs == 16)
1168           fprintf (file, "%%hi8(");
1169         else
1170           gcc_unreachable ();
1171         rl78_print_operand_1 (file, XEXP (op, 0), 0);
1172         fprintf (file, ")");
1173       }
1174       break;
1175
1176     case ZERO_EXTEND:
1177       if (GET_CODE (XEXP (op, 0)) == REG)
1178         fprintf (file, "%s", reg_names [REGNO (XEXP (op, 0))]);
1179       else
1180         print_rtl (file, op);
1181       break;
1182
1183     case PLUS:
1184       need_paren = 0;
1185       if (letter == 'H')
1186         {
1187           fprintf (file, "%%hi16(");
1188           need_paren = 1;
1189           letter = 0;
1190         }
1191       if (letter == 'h')
1192         {
1193           fprintf (file, "%%lo16(");
1194           need_paren = 1;
1195           letter = 0;
1196         }
1197       if (letter == 'e')
1198         {
1199           fprintf (file, "%%hi8(");
1200           need_paren = 1;
1201           letter = 0;
1202         }
1203       if (letter == 'q' || letter == 'Q')
1204         output_operand_lossage ("q/Q modifiers invalid for symbol references");
1205
1206       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
1207         {
1208           rl78_print_operand_1 (file, XEXP (op, 1), letter);
1209           fprintf (file, "+");
1210           rl78_print_operand_1 (file, XEXP (op, 0), letter);
1211         }
1212       else
1213         {
1214           rl78_print_operand_1 (file, XEXP (op, 0), letter);
1215           fprintf (file, "+");
1216           rl78_print_operand_1 (file, XEXP (op, 1), letter);
1217         }
1218       if (need_paren)
1219         fprintf (file, ")");
1220       break;
1221
1222     case SYMBOL_REF:
1223       need_paren = 0;
1224       if (letter == 'H')
1225         {
1226           fprintf (file, "%%hi16(");
1227           need_paren = 1;
1228           letter = 0;
1229         }
1230       if (letter == 'h')
1231         {
1232           fprintf (file, "%%lo16(");
1233           need_paren = 1;
1234           letter = 0;
1235         }
1236       if (letter == 'e')
1237         {
1238           fprintf (file, "%%hi8(");
1239           need_paren = 1;
1240           letter = 0;
1241         }
1242       if (letter == 'q' || letter == 'Q')
1243         output_operand_lossage ("q/Q modifiers invalid for symbol references");
1244
1245       output_addr_const (file, op);
1246       if (need_paren)
1247         fprintf (file, ")");
1248       break;
1249
1250     case CODE_LABEL:
1251     case LABEL_REF:
1252       output_asm_label (op);
1253       break;
1254
1255     case LTU:
1256       fprintf (file, letter == 'c' ? "nc" : "c");
1257       break;
1258     case LEU:
1259       fprintf (file, letter == 'c' ? "h" : "nh");
1260       break;
1261     case GEU:
1262       fprintf (file, letter == 'c' ? "c" : "nc");
1263       break;
1264     case GTU:
1265       fprintf (file, letter == 'c' ? "nh" : "h");
1266       break;
1267     case EQ:
1268       fprintf (file, letter == 'c' ? "nz" : "z");
1269       break;
1270     case NE:
1271       fprintf (file, letter == 'c' ? "z" : "nz");
1272       break;
1273
1274     default:
1275       fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
1276       break;
1277     }
1278 }
1279
1280 #undef  TARGET_PRINT_OPERAND
1281 #define TARGET_PRINT_OPERAND            rl78_print_operand
1282
1283 static void
1284 rl78_print_operand (FILE * file, rtx op, int letter)
1285 {
1286   if (CONSTANT_P (op) && letter != 'u')
1287     fprintf (file, "#");
1288   rl78_print_operand_1 (file, op, letter);
1289 }
1290
1291 #undef  TARGET_TRAMPOLINE_INIT
1292 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
1293
1294 /* Note that the RL78's addressing makes it very difficult to do
1295    trampolines on the stack.  So, libgcc has a small pool of
1296    trampolines from which one is allocated to this task.  */
1297 static void
1298 rl78_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
1299 {
1300   rtx mov_addr, thunk_addr;
1301   rtx function = XEXP (DECL_RTL (fndecl), 0);
1302
1303   mov_addr = adjust_address (m_tramp, HImode, 0);
1304   thunk_addr = gen_reg_rtx (HImode);
1305
1306   function = force_reg (HImode, function);
1307   static_chain = force_reg (HImode, static_chain);
1308
1309   emit_insn (gen_trampoline_init (thunk_addr, function, static_chain));
1310   emit_move_insn (mov_addr, thunk_addr);
1311
1312   cfun->machine->trampolines_used = 1;
1313 }
1314
1315 #undef  TARGET_TRAMPOLINE_ADJUST_ADDRESS
1316 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS rl78_trampoline_adjust_address
1317
1318 static rtx
1319 rl78_trampoline_adjust_address (rtx m_tramp)
1320 {
1321   rtx x = gen_rtx_MEM (HImode, m_tramp);
1322   return x;
1323 }
1324 \f
1325 /* Expander for cbranchqi4 and cbranchhi4.  RL78 is missing some of
1326    the "normal" compares, specifically, it only has unsigned compares,
1327    so we must synthesize the missing ones.  */
1328 void
1329 rl78_expand_compare (rtx *operands)
1330 {
1331   /* RL78 does not have signed comparisons.  We must modify the
1332      operands to be in the unsigned range, and emit an unsigned
1333      comparison.  */
1334
1335   enum machine_mode mode;
1336   rtx high_bit;
1337   int i;
1338   RTX_CODE new_cond;
1339
1340   switch (GET_CODE (operands[0]))
1341     {
1342     case GE:
1343       new_cond = GEU;
1344       break;
1345     case LE:
1346       new_cond = LEU;
1347       break;
1348     case GT:
1349       new_cond = GTU;
1350       break;
1351     case LT:
1352       new_cond = LTU;
1353       break;
1354     default:
1355       return;
1356     }
1357
1358 #if DEBUG0
1359   fprintf (stderr, "\033[38;5;129mrl78_expand_compare\n");
1360   debug_rtx (operands[0]);
1361   fprintf (stderr, "\033[0m");
1362 #endif
1363
1364   mode = GET_MODE (operands[1]);
1365   if (mode == VOIDmode)
1366     mode = GET_MODE (operands[2]);
1367   high_bit = GEN_INT (~0 << (GET_MODE_BITSIZE (mode) - 1));
1368
1369   /* 0: conditional 1,2: operands */
1370   for (i = 1; i <= 2; i ++)
1371     {
1372       rtx r = operands[i];
1373
1374       if (GET_CODE (r) == CONST_INT)
1375         r = GEN_INT (INTVAL (r) ^ INTVAL (high_bit));
1376       else
1377         {
1378           r = gen_rtx_PLUS (mode, operands[i], high_bit);
1379           r = copy_to_mode_reg (mode, r);
1380         }
1381       operands[i] = r;
1382     }
1383
1384   operands[0] = gen_rtx_fmt_ee (new_cond, GET_MODE (operands[0]), operands[1], operands[2]);
1385
1386 #if DEBUG0
1387   fprintf (stderr, "\033[38;5;142mrl78_expand_compare\n");
1388   debug_rtx (operands[0]);
1389   fprintf (stderr, "\033[0m");
1390 #endif
1391 }
1392
1393 \f
1394
1395 /* Define this to 1 if you are debugging the peephole optimizers.  */
1396 #define DEBUG_PEEP 0
1397
1398 /* Predicate used to enable the peephole2 patterns in rl78-virt.md.
1399    The default "word" size is a byte so we can effectively use all the
1400    registers, but we want to do 16-bit moves whenever possible.  This
1401    function determines when such a move is an option.  */
1402 bool
1403 rl78_peep_movhi_p (rtx *operands)
1404 {
1405   int i;
1406   rtx m, a;
1407
1408   /* (set (op0) (op1))
1409      (set (op2) (op3)) */
1410
1411 #if DEBUG_PEEP
1412   fprintf (stderr, "\033[33m");
1413   debug_rtx(operands[0]);
1414   debug_rtx(operands[1]);
1415   debug_rtx(operands[2]);
1416   debug_rtx(operands[3]);
1417   fprintf (stderr, "\033[0m");
1418 #endif
1419
1420   if (rtx_equal_p (operands[0], operands[3]))
1421     {
1422 #if DEBUG_PEEP
1423       fprintf (stderr, "no peep: overlapping\n");
1424 #endif
1425       return false;
1426     }
1427
1428   for (i = 0; i < 2; i ++)
1429     {
1430       if (GET_CODE (operands[i]) != GET_CODE (operands[i+2]))
1431         {
1432 #if DEBUG_PEEP
1433           fprintf (stderr, "no peep: different codes\n");
1434 #endif
1435           return false;
1436         }
1437       if (GET_MODE (operands[i]) != GET_MODE (operands[i+2]))
1438         {
1439 #if DEBUG_PEEP
1440           fprintf (stderr, "no peep: different modes\n");
1441 #endif
1442           return false;
1443         }
1444
1445       switch (GET_CODE (operands[i]))
1446         {
1447         case REG:
1448           /*   LSB                      MSB  */
1449           if (REGNO (operands[i]) + 1 != REGNO (operands[i+2])
1450               || GET_MODE (operands[i]) != QImode)
1451             {
1452 #if DEBUG_PEEP
1453               fprintf (stderr, "no peep: wrong regnos %d %d %d\n",
1454                        REGNO (operands[i]), REGNO (operands[i+2]),
1455                        i);
1456 #endif
1457               return false;
1458             }
1459           if (! rl78_hard_regno_mode_ok (REGNO (operands[i]), HImode))
1460             {
1461 #if DEBUG_PEEP
1462               fprintf (stderr, "no peep: reg %d not HI\n", REGNO (operands[i]));
1463 #endif
1464               return false;
1465             }
1466           break;
1467
1468         case CONST_INT:
1469           break;
1470
1471         case MEM:
1472           if (GET_MODE (operands[i]) != QImode)
1473             return false;
1474           if (MEM_ALIGN (operands[i]) < 16)
1475             return false;
1476           a = XEXP (operands[i], 0);
1477           if (GET_CODE (a) == CONST)
1478             a = XEXP (a, 0);
1479           if (GET_CODE (a) == PLUS)
1480             a = XEXP (a, 1);
1481           if (GET_CODE (a) == CONST_INT
1482               && INTVAL (a) & 1)
1483             {
1484 #if DEBUG_PEEP
1485               fprintf (stderr, "no peep: misaligned mem %d\n", i);
1486               debug_rtx (operands[i]);
1487 #endif
1488               return false;
1489             }
1490           m = adjust_address (operands[i], QImode, 1);
1491           if (! rtx_equal_p (m, operands[i+2]))
1492             {
1493 #if DEBUG_PEEP
1494               fprintf (stderr, "no peep: wrong mem %d\n", i);
1495               debug_rtx(m);
1496               debug_rtx (operands[i+2]);
1497 #endif
1498               return false;
1499             }
1500           break;
1501
1502         default:
1503 #if DEBUG_PEEP
1504           fprintf (stderr, "no peep: wrong rtx %d\n", i);
1505 #endif
1506           return false;
1507         }
1508     }
1509 #if DEBUG_PEEP
1510   fprintf (stderr, "\033[32mpeep!\033[0m\n");
1511 #endif
1512   return true;
1513 }
1514
1515 /* Likewise, when a peephole is activated, this function helps compute
1516    the new operands.  */
1517 void
1518 rl78_setup_peep_movhi (rtx *operands)
1519 {
1520   int i;
1521
1522   for (i = 0; i < 2; i ++)
1523     {
1524       switch (GET_CODE (operands[i]))
1525         {
1526         case REG:
1527           operands[i+4] = gen_rtx_REG (HImode, REGNO (operands[i]));
1528           break;
1529
1530         case CONST_INT:
1531           operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char)INTVAL (operands[i+2])) * 256);
1532           break;
1533
1534         case MEM:
1535           operands[i+4] = adjust_address (operands[i], HImode, 0);
1536           break;
1537
1538         default:
1539           break;
1540         }
1541     }
1542 }
1543 \f
1544 /*
1545         How Devirtualization works in the RL78 GCC port
1546
1547 Background
1548
1549 The RL78 is an 8-bit port with some 16-bit operations.  It has 32
1550 bytes of register space, in four banks, memory-mapped.  One bank is
1551 the "selected" bank and holds the registers used for primary
1552 operations.  Since the registers are memory mapped, often you can
1553 still refer to the unselected banks via memory accesses.
1554
1555 Virtual Registers
1556
1557 The GCC port uses bank 0 as the "selected" registers (A, X, BC, etc)
1558 and refers to the other banks via their memory addresses, although
1559 they're treated as regular registers internally.  These "virtual"
1560 registers are R8 through R23 (bank3 is reserved for asm-based
1561 interrupt handlers).
1562
1563 There are four machine description files:
1564
1565 rl78.md        - common register-independent patterns and definitions
1566 rl78-expand.md - expanders
1567 rl78-virt.md   - patterns that match BEFORE devirtualization
1568 rl78-real.md   - patterns that match AFTER devirtualization
1569
1570 At least through register allocation and reload, gcc is told that it
1571 can do pretty much anything - but may only use the virtual registers.
1572 GCC cannot properly create the varying addressing modes that the RL78
1573 supports in an efficient way.
1574
1575 Sometime after reload, the RL78 backend "devirtualizes" the RTL.  It
1576 uses the "valloc" attribute in rl78-virt.md for determining the rules
1577 by which it will replace virtual registers with real registers (or
1578 not) and how to make up addressing modes.  For example, insns tagged
1579 with "ro1" have a single read-only parameter, which may need to be
1580 moved from memory/constant/vreg to a suitable real register.  As part
1581 of devirtualization, a flag is toggled, disabling the rl78-virt.md
1582 patterns and enabling the rl78-real.md patterns.  The new patterns'
1583 constraints are used to determine the real registers used.  NOTE:
1584 patterns in rl78-virt.md essentially ignore the constrains and rely on
1585 predicates, where the rl78-real.md ones essentially ignore the
1586 predicates and rely on the constraints.
1587
1588 The devirtualization pass is scheduled via the pass manager (despite
1589 being called "rl78_reorg") so it can be scheduled prior to var-track
1590 (the idea is to let gdb know about the new registers).  Ideally, it
1591 would be scheduled right after pro/epilogue generation, so the
1592 post-reload optimizers could operate on the real registers, but when I
1593 tried that there were some issues building the target libraries.
1594
1595 During devirtualization, a simple register move optimizer is run.  It
1596 would be better to run a full CSE/propogation pass on it through, or
1597 re-run regmove, but that has not yet been attempted.
1598
1599  */
1600 #define DEBUG_ALLOC 0
1601
1602 /* Rescans an insn to see if it's recognized again.  This is done
1603    carefully to ensure that all the constraint information is accurate
1604    for the newly matched insn.  */
1605 static bool
1606 insn_ok_now (rtx insn)
1607 {
1608   INSN_CODE (insn) = -1;
1609   if (recog (PATTERN (insn), insn, 0) > -1)
1610     {
1611       extract_insn (insn);
1612       if (constrain_operands (1))
1613         {
1614 #if DEBUG_ALLOC
1615           fprintf (stderr, "\033[32m");
1616           debug_rtx (insn);
1617           fprintf (stderr, "\033[0m");
1618 #endif
1619           return true;
1620         }
1621     }
1622   else
1623     {
1624       fprintf (stderr, "\033[41;30m Unrecognized insn \033[0m\n");
1625       debug_rtx (insn);
1626       gcc_unreachable ();
1627     }
1628 #if DEBUG_ALLOC
1629   fprintf (stderr, "\033[31m");
1630   debug_rtx (insn);
1631   fprintf (stderr, "\033[0m");
1632 #endif
1633   return false;
1634 }
1635
1636 #if DEBUG_ALLOC
1637 #define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__)
1638 #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__)
1639 #define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable()
1640 #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; }
1641 #else
1642 #define WORKED
1643 #define FAILEDSOFAR
1644 #define FAILED gcc_unreachable ()
1645 #define MAYBE_OK(insn) if (insn_ok_now (insn)) return;
1646 #endif
1647
1648 /* Registers into which we move the contents of virtual registers.  */
1649 #define X gen_rtx_REG (QImode, 0)
1650 #define A gen_rtx_REG (QImode, 1)
1651 #define C gen_rtx_REG (QImode, 2)
1652 #define B gen_rtx_REG (QImode, 3)
1653 #define E gen_rtx_REG (QImode, 4)
1654 #define D gen_rtx_REG (QImode, 5)
1655 #define L gen_rtx_REG (QImode, 6)
1656 #define H gen_rtx_REG (QImode, 7)
1657
1658 #define AX gen_rtx_REG (HImode, 0)
1659 #define BC gen_rtx_REG (HImode, 2)
1660 #define DE gen_rtx_REG (HImode, 4)
1661 #define HL gen_rtx_REG (HImode, 6)
1662
1663 #define OP(x) (*recog_data.operand_loc[x])
1664
1665 /* Returns TRUE if R is a virtual register.  */
1666 static bool
1667 is_virtual_register (rtx r)
1668 {
1669   return (GET_CODE (r) == REG
1670           && REGNO (r) >= 8
1671           && REGNO (r) < 24);
1672 }
1673
1674 /* In all these alloc routines, we expect the following: the insn
1675    pattern is unshared, the insn was previously recognized and failed
1676    due to predicates or constraints, and the operand data is in
1677    recog_data.  */
1678
1679 static int virt_insn_was_frame;
1680
1681 /* Hook for all insns we emit.  Re-mark them as FRAME_RELATED if
1682    needed.  */
1683 static rtx
1684 EM2 (int line ATTRIBUTE_UNUSED, rtx r)
1685 {
1686 #if DEBUG_ALLOC
1687   fprintf (stderr, "\033[36m%d: ", line);
1688   debug_rtx(r);
1689   fprintf (stderr, "\033[0m");
1690 #endif
1691   /*SCHED_GROUP_P (r) = 1;*/
1692   if (virt_insn_was_frame)
1693     RTX_FRAME_RELATED_P (r) = 1;
1694   return r;
1695 }
1696
1697 #define EM(x) EM2 (__LINE__, x)
1698
1699 /* Return a suitable RTX for the low half of a __far address.  */
1700 static rtx
1701 rl78_lo16 (rtx addr)
1702 {
1703   if (GET_CODE (addr) == SYMBOL_REF
1704       || GET_CODE (addr) == CONST)
1705     {
1706       rtx r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0));
1707       r = gen_rtx_CONST (HImode, r);
1708       return r;
1709     }
1710   return rl78_subreg (HImode, addr, SImode, 0);
1711 }
1712
1713 /* Return a suitable RTX for the high half's lower byte of a __far address.  */
1714 static rtx
1715 rl78_hi8 (rtx addr)
1716 {
1717   if (GET_CODE (addr) == SYMBOL_REF
1718       || GET_CODE (addr) == CONST)
1719     {
1720       rtx r = gen_rtx_ZERO_EXTRACT (QImode, addr, GEN_INT (8), GEN_INT (16));
1721       r = gen_rtx_CONST (QImode, r);
1722       return r;
1723     }
1724   return rl78_subreg (QImode, addr, SImode, 2);
1725 }
1726
1727 /* Copy any register values into real registers and return an RTX for
1728    the same memory, now addressed by real registers.  Any needed insns
1729    are emitted before BEFORE.  */
1730 static rtx
1731 transcode_memory_rtx (rtx m, rtx newbase, rtx before)
1732 {
1733   rtx base, index, addendr;
1734   int addend = 0;
1735
1736   if (GET_CODE (m) != MEM)
1737     return m;
1738
1739   if (GET_MODE (XEXP (m, 0)) == SImode)
1740     {
1741       rtx seg = rl78_hi8 (XEXP (m, 0));
1742 #if DEBUG_ALLOC
1743       fprintf (stderr, "setting ES:\n");
1744       debug_rtx(seg);
1745 #endif
1746       emit_insn_before (EM(gen_movqi (A, seg)), before);
1747       emit_insn_before (EM(gen_movqi_es (A)), before);
1748       m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
1749     }
1750
1751   characterize_address (XEXP (m, 0), &base, &index, &addendr);
1752   gcc_assert (index == NULL_RTX);
1753
1754 #if DEBUG_ALLOC
1755   fprintf (stderr, "\033[33m"); debug_rtx(m); fprintf (stderr, "\033[0m");
1756   debug_rtx (base);
1757 #endif
1758   if (base == NULL_RTX)
1759     return m;
1760
1761   if (addendr && GET_CODE (addendr) == CONST_INT)
1762     addend = INTVAL (addendr);
1763
1764   if (REGNO (base) == SP_REG)
1765     {
1766       if (addend >= 0 && addend  <= 255)
1767         return m;
1768     }
1769
1770   /* BASE should be a virtual register.  We copy it to NEWBASE.  If
1771      the addend is out of range for DE/HL, we use AX to compute the full
1772      address.  */
1773
1774   if (addend < 0
1775       || (addend > 255 && REGNO (newbase) != 2)
1776       || (addendr && GET_CODE (addendr) != CONST_INT))
1777     {
1778       /* mov ax, vreg
1779          add ax, #imm
1780          mov hl, ax     */
1781       EM (emit_insn_before (gen_movhi (AX, base), before));
1782       EM (emit_insn_before (gen_addhi3 (AX, AX, addendr), before));
1783       EM (emit_insn_before (gen_movhi (newbase, AX), before));
1784       base = newbase;
1785       addend = 0;
1786     }
1787   else
1788     {
1789       EM (emit_insn_before (gen_movhi (newbase, base), before));
1790       base = newbase;
1791     }
1792
1793   if (addend)
1794     base = gen_rtx_PLUS (HImode, base, GEN_INT (addend));
1795
1796 #if DEBUG_ALLOC
1797   fprintf (stderr, "\033[33m");
1798   debug_rtx (m);
1799 #endif
1800   m = change_address (m, GET_MODE (m), base);
1801 #if DEBUG_ALLOC
1802   debug_rtx (m);
1803   fprintf (stderr, "\033[0m");
1804 #endif
1805   return m;
1806 }
1807
1808 /* Copy SRC to accumulator (A or AX), placing any generated insns
1809    before BEFORE.  Returns accumulator RTX.  */
1810
1811 static rtx
1812 move_to_acc (int opno, rtx before)
1813 {
1814   rtx src = OP(opno);
1815   enum machine_mode mode = GET_MODE (src);
1816
1817   if (GET_CODE (src) == REG
1818       && REGNO (src) < 2)
1819     return src;
1820
1821   if (mode == VOIDmode)
1822     mode = recog_data.operand_mode[opno];
1823
1824   if (mode == QImode)
1825     {
1826       EM (emit_insn_before (gen_movqi (A, src), before));
1827       return A;
1828     }
1829   else
1830     {
1831       EM (emit_insn_before (gen_movhi (AX, src), before));
1832       return AX;
1833     }
1834 }
1835
1836 /* Copy accumulator (A or AX) to DEST, placing any generated insns
1837    after AFTER.  Returns accumulator RTX.  */
1838
1839 static rtx
1840 move_from_acc (rtx dest, rtx after)
1841 {
1842   enum machine_mode mode = GET_MODE (dest);
1843
1844   if (REG_P (dest) && REGNO (dest) < 2)
1845     return dest;
1846
1847   if (mode == QImode)
1848     {
1849       EM (emit_insn_after (gen_movqi (dest, A), after));
1850       return A;
1851     }
1852   else
1853     {
1854       EM (emit_insn_after (gen_movhi (dest, AX), after));
1855       return AX;
1856     }
1857 }
1858
1859 /* Copy accumulator (A or AX) to REGNO, placing any generated insns
1860    before BEFORE.  Returns reg RTX.  */
1861
1862 static rtx
1863 move_acc_to_reg (rtx acc, int regno, rtx before)
1864 {
1865   enum machine_mode mode = GET_MODE (acc);
1866   rtx reg;
1867
1868   reg = gen_rtx_REG (mode, regno);
1869
1870   if (mode == QImode)
1871     {
1872       EM (emit_insn_before (gen_movqi (reg, A), before));
1873       return reg;
1874     }
1875   else
1876     {
1877       EM (emit_insn_before (gen_movhi (reg, AX), before));
1878       return reg;
1879     }
1880 }
1881
1882 /* Copy SRC to X, placing any generated insns before BEFORE.
1883    Returns X RTX.  */
1884
1885 static rtx
1886 move_to_x (int opno, rtx before)
1887 {
1888   rtx src = OP(opno);
1889   enum machine_mode mode = GET_MODE (src);
1890   rtx reg;
1891
1892   if (mode == VOIDmode)
1893     mode = recog_data.operand_mode[opno];
1894   reg = (mode == QImode) ? X : AX;
1895
1896   if (mode == QImode || ! is_virtual_register (OP (opno)))
1897     {
1898       OP(opno) = move_to_acc (opno, before);
1899       OP(opno) = move_acc_to_reg (OP(opno), X_REG, before);
1900       return reg;
1901     }
1902
1903   if (mode == QImode)
1904     EM (emit_insn_before (gen_movqi (reg, src), before));
1905   else
1906     EM (emit_insn_before (gen_movhi (reg, src), before));
1907
1908   return reg;
1909 }
1910
1911 /* Copy OP(opno) to H or HL, placing any generated insns before BEFORE.
1912    Returns H/HL RTX.  */
1913
1914 static rtx
1915 move_to_hl (int opno, rtx before)
1916 {
1917   rtx src = OP (opno);
1918   enum machine_mode mode = GET_MODE (src);
1919   rtx reg;
1920
1921   if (mode == VOIDmode)
1922     mode = recog_data.operand_mode[opno];
1923   reg = (mode == QImode) ? L : HL;
1924
1925   if (mode == QImode || ! is_virtual_register (OP (opno)))
1926     {
1927       OP (opno) = move_to_acc (opno, before);
1928       OP (opno) = move_acc_to_reg (OP (opno), L_REG, before);
1929       return reg;
1930     }
1931
1932   if (mode == QImode)
1933     EM (emit_insn_before (gen_movqi (reg, src), before));
1934   else
1935     EM (emit_insn_before (gen_movhi (reg, src), before));
1936
1937   return reg;
1938 }
1939
1940 /* Copy OP(opno) to E or DE, placing any generated insns before BEFORE.
1941    Returns E/DE RTX.  */
1942
1943 static rtx
1944 move_to_de (int opno, rtx before)
1945 {
1946   rtx src = OP (opno);
1947   enum machine_mode mode = GET_MODE (src);
1948   rtx reg;
1949
1950   if (mode == VOIDmode)
1951     mode = recog_data.operand_mode[opno];
1952
1953   reg = (mode == QImode) ? E : DE;
1954
1955   if (mode == QImode || ! is_virtual_register (OP (opno)))
1956     {
1957       OP (opno) = move_to_acc (opno, before);
1958       OP (opno) = move_acc_to_reg (OP (opno), E_REG, before);
1959     }
1960   else
1961     {
1962       rtx move = mode == QImode ? gen_movqi (reg, src) : gen_movhi (reg, src);
1963
1964       EM (emit_insn_before (move, before));
1965     }
1966
1967   return reg;
1968 }
1969
1970 /* Devirtualize an insn of the form (SET (op) (unop (op))).  */
1971 static void
1972 rl78_alloc_physical_registers_op1 (rtx insn)
1973 {
1974   /* op[0] = func op[1] */
1975
1976   /* We first try using A as the destination, then copying it
1977      back.  */
1978   if (rtx_equal_p (OP(0), OP(1)))
1979     {
1980       OP(0) =
1981       OP(1) = transcode_memory_rtx (OP(1), DE, insn);
1982     }
1983   else
1984     {
1985       OP(0) = transcode_memory_rtx (OP(0), BC, insn);
1986       OP(1) = transcode_memory_rtx (OP(1), HL, insn);
1987     }
1988
1989   MAYBE_OK (insn);
1990
1991   OP(0) = move_from_acc (OP(0), insn);
1992
1993   MAYBE_OK (insn);
1994
1995   /* Try copying the src to acc first, then.  This is for, for
1996      example, ZERO_EXTEND or NOT.  */
1997   OP(1) = move_to_acc (1, insn);
1998
1999   MAYBE_OK (insn);
2000
2001   FAILED;
2002 }
2003
2004 /* Devirtualize an insn of the form (SET (op) (unop (op) (op))).  */
2005 static void
2006 rl78_alloc_physical_registers_op2 (rtx insn)
2007 {
2008   /* op[0] = op[1] func op[2] */
2009   rtx prev = prev_nonnote_nondebug_insn (insn);
2010   rtx first;
2011   bool hl_used;
2012
2013   if (rtx_equal_p (OP(0), OP(1)))
2014     {
2015       OP(0) =
2016       OP(1) = transcode_memory_rtx (OP(1), DE, insn);
2017       prev = next_nonnote_nondebug_insn (prev);
2018       OP(2) = transcode_memory_rtx (OP(2), HL, insn);
2019       prev = prev_nonnote_nondebug_insn (prev);
2020     }
2021   else if (rtx_equal_p (OP(0), OP(2)))
2022     {
2023       OP(1) = transcode_memory_rtx (OP(1), DE, insn);
2024       prev = next_nonnote_nondebug_insn (prev);
2025       OP(0) =
2026       OP(2) = transcode_memory_rtx (OP(2), HL, insn);
2027       prev = prev_nonnote_nondebug_insn (prev);
2028     }
2029   else
2030     {
2031       OP(0) = transcode_memory_rtx (OP(0), BC, insn);
2032       OP(1) = transcode_memory_rtx (OP(1), DE, insn);
2033       prev = next_nonnote_nondebug_insn (prev);
2034       OP(2) = transcode_memory_rtx (OP(2), HL, insn);
2035     }
2036
2037   MAYBE_OK (insn);
2038
2039   prev = prev_nonnote_nondebug_insn (insn);
2040   if (recog_data.constraints[1][0] == '%'
2041       && is_virtual_register (OP (1))
2042       && ! is_virtual_register (OP (2))
2043       && ! CONSTANT_P (OP (2)))
2044     {
2045       rtx tmp = OP (1);
2046       OP (1) = OP (2);
2047       OP (2) = tmp;
2048     }
2049
2050   /* Make a note of wether (H)L is being used.  It matters
2051      because if OP(2) alsoneeds reloading, then we must take
2052      care not to corrupt HL.  */
2053   hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1));
2054
2055   OP(0) = move_from_acc (OP (0), insn);
2056   OP(1) = move_to_acc (1, insn);
2057
2058   MAYBE_OK (insn);
2059
2060   /* We have to copy op2 to HL, but that involves AX, which
2061      already has a live value.  Emit it before those insns.  */
2062
2063   if (prev)
2064     first = next_nonnote_nondebug_insn (prev);
2065   else
2066     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
2067       ;
2068
2069   OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first);
2070   
2071   MAYBE_OK (insn);
2072   
2073   FAILED;
2074 }
2075
2076 /* Devirtualize an insn of the form (SET () (unop (op))).  */
2077
2078 static void
2079 rl78_alloc_physical_registers_ro1 (rtx insn)
2080 {
2081   /* (void) op[0] */
2082   OP(0) = transcode_memory_rtx (OP(0), BC, insn);
2083
2084   MAYBE_OK (insn);
2085
2086   OP(0) = move_to_acc (0, insn);
2087
2088   MAYBE_OK (insn);
2089
2090   FAILED;
2091 }
2092
2093 /* Devirtualize a compare insn.  */
2094 static void
2095 rl78_alloc_physical_registers_cmp (rtx insn)
2096 {
2097   /* op[1] cmp_op[0] op[2] */
2098   rtx prev = prev_nonnote_nondebug_insn (insn);
2099   rtx first;
2100
2101   OP(1) = transcode_memory_rtx (OP(1), DE, insn);
2102   OP(2) = transcode_memory_rtx (OP(2), HL, insn);
2103
2104   MAYBE_OK (insn);
2105
2106   OP(1) = move_to_acc (1, insn);
2107
2108   MAYBE_OK (insn);
2109
2110   /* We have to copy op2 to HL, but that involves the acc, which
2111      already has a live value.  Emit it before those insns.  */
2112
2113   if (prev)
2114     first = next_nonnote_nondebug_insn (prev);
2115   else
2116     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
2117       ;
2118   OP(2) = move_to_hl (2, first);
2119
2120   MAYBE_OK (insn);
2121
2122   FAILED;
2123 }
2124
2125 /* Like op2, but AX = A op X.  */
2126 static void
2127 rl78_alloc_physical_registers_umul (rtx insn)
2128 {
2129   /* op[0] = op[1] func op[2] */
2130   rtx prev = prev_nonnote_nondebug_insn (insn);
2131   rtx first;
2132
2133   OP(0) = transcode_memory_rtx (OP(0), BC, insn);
2134   OP(1) = transcode_memory_rtx (OP(1), DE, insn);
2135   OP(2) = transcode_memory_rtx (OP(2), HL, insn);
2136
2137   MAYBE_OK (insn);
2138
2139   if (recog_data.constraints[1][0] == '%'
2140       && is_virtual_register (OP(1))
2141       && !is_virtual_register (OP(2))
2142       && !CONSTANT_P (OP(2)))
2143     {
2144       rtx tmp = OP(1);
2145       OP(1) = OP(2);
2146       OP(2) = tmp;
2147     }
2148
2149   OP(0) = move_from_acc (OP(0), insn);
2150   OP(1) = move_to_acc (1, insn);
2151
2152   MAYBE_OK (insn);
2153
2154   /* We have to copy op2 to X, but that involves the acc, which
2155      already has a live value.  Emit it before those insns.  */
2156
2157   if (prev)
2158     first = next_nonnote_nondebug_insn (prev);
2159   else
2160     for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first))
2161       ;
2162   OP(2) = move_to_x (2, first);
2163
2164   MAYBE_OK (insn);
2165
2166   FAILED;
2167 }
2168
2169 /* Scan all insns and devirtualize them.  */
2170 static void
2171 rl78_alloc_physical_registers (void)
2172 {
2173   /* During most of the compile, gcc is dealing with virtual
2174      registers.  At this point, we need to assign physical registers
2175      to the vitual ones, and copy in/out as needed.  */
2176
2177   rtx insn, curr;
2178   enum attr_valloc valloc_method;
2179
2180   for (insn = get_insns (); insn; insn = curr)
2181     {
2182       int i;
2183
2184       curr = next_nonnote_nondebug_insn (insn);
2185
2186       if (INSN_P (insn)
2187           && (GET_CODE (PATTERN (insn)) == SET
2188               || GET_CODE (PATTERN (insn)) == CALL)
2189           && INSN_CODE (insn) == -1)
2190         {
2191           if (GET_CODE (SET_SRC (PATTERN (insn))) == ASM_OPERANDS)
2192             continue;
2193           i = recog (PATTERN (insn), insn, 0);
2194           if (i == -1)
2195             {
2196               debug_rtx (insn);
2197               gcc_unreachable ();
2198             }
2199           INSN_CODE (insn) = i;
2200         }
2201     }
2202
2203   cfun->machine->virt_insns_ok = 0;
2204   cfun->machine->real_insns_ok = 1;
2205
2206   for (insn = get_insns (); insn; insn = curr)
2207     {
2208       curr = insn ? next_nonnote_nondebug_insn (insn) : NULL;
2209
2210       if (!INSN_P (insn))
2211         continue;
2212       if (GET_CODE (PATTERN (insn)) != SET
2213           && GET_CODE (PATTERN (insn)) != CALL)
2214           continue;
2215
2216       if (GET_CODE (SET_SRC (PATTERN (insn))) == ASM_OPERANDS)
2217         continue;
2218
2219       valloc_method = get_attr_valloc (insn);
2220
2221       PATTERN (insn)= copy_rtx_if_shared (PATTERN (insn));
2222
2223       if (insn_ok_now (insn))
2224         continue;
2225
2226       INSN_CODE (insn) = -1;
2227
2228       if (RTX_FRAME_RELATED_P (insn))
2229         virt_insn_was_frame = 1;
2230       else
2231         virt_insn_was_frame = 0;
2232
2233       switch (valloc_method)
2234         {
2235         case VALLOC_OP1:
2236           rl78_alloc_physical_registers_op1 (insn);
2237           break;
2238         case VALLOC_OP2:
2239           rl78_alloc_physical_registers_op2 (insn);
2240           break;
2241         case VALLOC_RO1:
2242           rl78_alloc_physical_registers_ro1 (insn);
2243           break;
2244         case VALLOC_CMP:
2245           rl78_alloc_physical_registers_cmp (insn);
2246           break;
2247         case VALLOC_UMUL:
2248           rl78_alloc_physical_registers_umul (insn);
2249           break;
2250         case VALLOC_MACAX:
2251           /* Macro that clobbers AX */
2252           break;
2253         }
2254     }
2255 #if DEBUG_ALLOC
2256   fprintf (stderr, "\033[0m");
2257 #endif
2258 }
2259
2260 /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN.
2261    This function scans for uses of registers; the last use (i.e. first
2262    encounter when scanning backwards) triggers a REG_DEAD note if the
2263    reg was previously in DEAD[].  */
2264 static void
2265 rl78_note_reg_uses (char *dead, rtx s, rtx insn)
2266 {
2267   const char *fmt;
2268   int i, r;
2269   enum rtx_code code;
2270
2271   if (!s)
2272     return;
2273
2274   code = GET_CODE (s);
2275
2276   switch (code)
2277     {
2278       /* Compare registers by number.  */
2279     case REG:
2280       r = REGNO (s);
2281       if (dump_file)
2282         {
2283           fprintf (dump_file, "note use reg %d size %d on insn %d\n",
2284                    r, GET_MODE_SIZE (GET_MODE (s)), INSN_UID (insn));
2285           print_rtl_single (dump_file, s);
2286         }
2287       if (dead [r])
2288         add_reg_note (insn, REG_DEAD, gen_rtx_REG (GET_MODE (s), r));
2289       for (i = 0; i < GET_MODE_SIZE (GET_MODE (s)); i ++)
2290         dead [r + i] = 0;
2291       return;
2292
2293       /* These codes have no constituent expressions
2294          and are unique.  */
2295     case SCRATCH:
2296     case CC0:
2297     case PC:
2298       return;
2299
2300     case CONST_INT:
2301     case CONST_VECTOR:
2302     case CONST_DOUBLE:
2303     case CONST_FIXED:
2304       /* These are kept unique for a given value.  */
2305       return;
2306
2307     default:
2308       break;
2309     }
2310
2311   fmt = GET_RTX_FORMAT (code);
2312
2313   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2314     {
2315       if (fmt[i] == 'E')
2316         {
2317           int j;
2318           for (j = XVECLEN (s, i) - 1; j >= 0; j--)
2319             rl78_note_reg_uses (dead, XVECEXP (s, i, j), insn);
2320         }
2321       else if (fmt[i] == 'e')
2322         rl78_note_reg_uses (dead, XEXP (s, i), insn);
2323     }
2324 }
2325
2326 /* Like the previous function, but scan for SETs instead.  */
2327 static void
2328 rl78_note_reg_set (char *dead, rtx d, rtx insn)
2329 {
2330   int r, i;
2331
2332   if (GET_CODE (d) != REG)
2333     return;
2334
2335   r = REGNO (d);
2336   if (dead [r])
2337     add_reg_note (insn, REG_UNUSED, gen_rtx_REG (GET_MODE (d), r));
2338   if (dump_file)
2339     fprintf (dump_file, "note set reg %d size %d\n", r, GET_MODE_SIZE (GET_MODE (d)));
2340   for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++)
2341     dead [r + i] = 1;
2342 }
2343
2344 /* This is a rather crude register death pass.  Death status is reset
2345    at every jump or call insn.  */
2346 static void
2347 rl78_calculate_death_notes (void)
2348 {
2349   char dead[FIRST_PSEUDO_REGISTER];
2350   rtx insn, p, s, d;
2351   int i;
2352
2353   memset (dead, 0, sizeof (dead));
2354
2355   for (insn = get_last_insn ();
2356        insn;
2357        insn = prev_nonnote_nondebug_insn (insn))
2358     {
2359       if (dump_file)
2360         {
2361           fprintf (dump_file, "\n--------------------------------------------------");
2362           fprintf (dump_file, "\nDead:");
2363           for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
2364             if (dead[i])
2365               fprintf(dump_file, " %s", reg_names[i]);
2366           fprintf (dump_file, "\n");
2367           print_rtl_single (dump_file, insn);
2368         }
2369
2370       switch (GET_CODE (insn))
2371         {
2372         case INSN:
2373           p = PATTERN (insn);
2374           switch (GET_CODE (p))
2375             {
2376             case SET:
2377               s = SET_SRC (p);
2378               d = SET_DEST (p);
2379               rl78_note_reg_set (dead, d, insn);
2380               rl78_note_reg_uses (dead, s, insn);
2381               break;
2382
2383             case USE:
2384               rl78_note_reg_uses (dead, p, insn);
2385               break;
2386
2387             default:
2388               break;
2389             }
2390           break;
2391
2392         case JUMP_INSN:
2393           if (INSN_CODE (insn) == CODE_FOR_return)
2394             {
2395               memset (dead, 1, sizeof (dead));
2396               /* We expect a USE just prior to this, which will mark
2397                  the actual return registers.  The USE will have a
2398                  death note, but we aren't going to be modifying it
2399                  after this pass.  */
2400               break;
2401             }
2402         case CALL_INSN:
2403           memset (dead, 0, sizeof (dead));
2404           break;
2405
2406         default:
2407           break;
2408         }
2409       if (dump_file)
2410         print_rtl_single (dump_file, insn);
2411     }
2412 }
2413
2414 /* Helper function to reset the origins in RP and the age in AGE for
2415    all registers.  */
2416 static void
2417 reset_origins (int *rp, int *age)
2418 {
2419   int i;
2420   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2421     {
2422       rp[i] = i;
2423       age[i] = 0;
2424     }
2425 }
2426
2427 /* The idea behind this optimization is to look for cases where we
2428    move data from A to B to C, and instead move from A to B, and A to
2429    C.  If B is a virtual register or memory, this is a big win on its
2430    own.  If B turns out to be unneeded after this, it's a bigger win.
2431    For each register, we try to determine where it's value originally
2432    came from, if it's propogated purely through moves (and not
2433    computes).  The ORIGINS[] array has the regno for the "origin" of
2434    the value in the [regno] it's indexed by.  */
2435 static void
2436 rl78_propogate_register_origins (void)
2437 {
2438   int origins[FIRST_PSEUDO_REGISTER];
2439   int age[FIRST_PSEUDO_REGISTER];
2440   int i;
2441   rtx insn, ninsn = NULL_RTX;
2442   rtx pat;
2443
2444   reset_origins (origins, age);
2445
2446   for (insn = get_insns (); insn; insn = ninsn)
2447     {
2448       ninsn = next_nonnote_nondebug_insn (insn);
2449
2450       if (dump_file)
2451         {
2452           fprintf (dump_file, "\n");
2453           fprintf (dump_file, "Origins:");
2454           for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++)
2455             if (origins[i] != i)
2456               fprintf (dump_file, " r%d=r%d", i, origins[i]);
2457           fprintf (dump_file, "\n");
2458           print_rtl_single (dump_file, insn);
2459         }
2460
2461       switch (GET_CODE (insn))
2462         {
2463         case CODE_LABEL:
2464         case BARRIER:
2465         case CALL_INSN:
2466         case JUMP_INSN:
2467           reset_origins (origins, age);
2468           break;
2469
2470         default:
2471           break;
2472
2473         case INSN:
2474           pat = PATTERN (insn);
2475
2476           if (GET_CODE (pat) == PARALLEL)
2477             {
2478               rtx clobber = XVECEXP (pat, 0, 1);
2479               pat = XVECEXP (pat, 0, 0);
2480               if (GET_CODE (clobber) == CLOBBER)
2481                 {
2482                   int cr = REGNO (XEXP (clobber, 0));
2483                   int mb = GET_MODE_SIZE (GET_MODE (XEXP (clobber, 0)));
2484                   if (dump_file)
2485                     fprintf (dump_file, "reset origins of %d regs at %d\n", mb, cr);
2486                   for (i = 0; i < mb; i++)
2487                     {
2488                       origins[cr + i] = cr + i;
2489                       age[cr + i] = 0;
2490                     }
2491                 }
2492               else
2493                 break;
2494             }
2495
2496           if (GET_CODE (pat) == SET)
2497             {
2498               rtx src = SET_SRC (pat);
2499               rtx dest = SET_DEST (pat);
2500               int mb = GET_MODE_SIZE (GET_MODE (dest));
2501
2502               if (GET_CODE (dest) == REG)
2503                 {
2504                   int dr = REGNO (dest);
2505
2506                   if (GET_CODE (src) == REG)
2507                     {
2508                       int sr = REGNO (src);
2509                       int same = 1;
2510                       int best_age, best_reg;
2511
2512                       /* See if the copy is not needed.  */
2513                       for (i = 0; i < mb; i ++)
2514                         if (origins[dr + i] != origins[sr + i])
2515                           same = 0;
2516                       if (same)
2517                         {
2518                           if (dump_file)
2519                             fprintf (dump_file, "deleting because dest already has correct value\n");
2520                           delete_insn (insn);
2521                           break;
2522                         }
2523
2524                       if (dr < 8 || sr >= 8)
2525                         {
2526                           int ar;
2527
2528                           best_age = -1;
2529                           best_reg = -1;
2530                           /* See if the copy can be made from another
2531                              bank 0 register instead, instead of the
2532                              virtual src register.  */
2533                           for (ar = 0; ar < 8; ar += mb)
2534                             {
2535                               same = 1;
2536                               for (i = 0; i < mb; i ++)
2537                                 if (origins[ar + i] != origins[sr + i])
2538                                   same = 0;
2539
2540                               /* The chip has some reg-reg move limitations.  */
2541                               if (mb == 1 && dr > 3)
2542                                 same = 0;
2543
2544                               if (same)
2545                                 {
2546                                   if (best_age == -1 || best_age > age[sr + i])
2547                                     {
2548                                       best_age = age[sr + i];
2549                                       best_reg = sr;
2550                                     }
2551                                 }
2552                             }
2553
2554                           if (best_reg != -1)
2555                             {
2556                               /* FIXME: copy debug info too.  */
2557                               SET_SRC (pat) = gen_rtx_REG (GET_MODE (src), best_reg);
2558                               sr = best_reg;
2559                             }
2560                         }
2561
2562                       for (i = 0; i < mb; i++)
2563                         {
2564                           origins[dr + i] = origins[sr + i];
2565                           age[dr + i] = age[sr + i] + 1;
2566                         }
2567                     }
2568                   else
2569                     {
2570                       /* The destination is computed, its origin is itself.  */
2571                       if (dump_file)
2572                         fprintf (dump_file, "resetting origin of r%d for %d byte%s\n",
2573                                  dr, mb, mb == 1 ? "" : "s");
2574                       for (i = 0; i < mb; i ++)
2575                         {
2576                           origins[dr + i] = dr + i;
2577                           age[dr + i] = 0;
2578                         }
2579                     }
2580
2581                   /* Any registers marked with that reg as an origin are reset.  */
2582                   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2583                     if (origins[i] >= dr && origins[i] < dr + mb)
2584                       {
2585                         origins[i] = i;
2586                         age[i] = 0;
2587                       }
2588                 }
2589
2590               /* Special case - our ADDSI3 macro uses AX */
2591               if (get_attr_valloc (insn) == VALLOC_MACAX)
2592                 {
2593                   if (dump_file)
2594                     fprintf (dump_file, "Resetting origin of AX for macro.\n");
2595                   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2596                     if (i <= 1 || origins[i] <= 1)
2597                       {
2598                         origins[i] = i;
2599                         age[i] = 0;
2600                       }
2601                 }
2602
2603               if (GET_CODE (src) == ASHIFT
2604                   || GET_CODE (src) == ASHIFTRT
2605                   || GET_CODE (src) == LSHIFTRT)
2606                 {
2607                   rtx count = XEXP (src, 1);
2608                   if (GET_CODE (count) == REG)
2609                     {
2610                       /* Special case - our pattern clobbers the count register.  */
2611                       int r = REGNO (count);
2612                       if (dump_file)
2613                         fprintf (dump_file, "Resetting origin of r%d for shift.\n", r);
2614                       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2615                         if (i == r || origins[i] == r)
2616                           {
2617                             origins[i] = i;
2618                             age[i] = 0;
2619                           }
2620                     }
2621                 }
2622             }
2623         }
2624     }
2625 }
2626
2627 /* Remove any SETs where the destination is unneeded.  */
2628 static void
2629 rl78_remove_unused_sets (void)
2630 {
2631   rtx insn, ninsn = NULL_RTX;
2632   rtx dest;
2633
2634   for (insn = get_insns (); insn; insn = ninsn)
2635     {
2636       ninsn = next_nonnote_nondebug_insn (insn);
2637
2638       if ((insn = single_set (insn)) == NULL_RTX)
2639         continue;
2640
2641       dest = SET_DEST (insn);
2642
2643       if (REGNO (dest) > 23)
2644         continue;
2645
2646       if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
2647         delete_insn (insn);
2648     }
2649 }
2650
2651 #undef  xTARGET_MACHINE_DEPENDENT_REORG
2652 #define xTARGET_MACHINE_DEPENDENT_REORG  rl78_reorg
2653
2654 /* This is the top of the devritualization pass.  */
2655 static void
2656 rl78_reorg (void)
2657 {
2658   rl78_alloc_physical_registers ();
2659
2660   if (dump_file)
2661     {
2662       fprintf (dump_file, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n");
2663       print_rtl_with_bb (dump_file, get_insns ());
2664     }
2665
2666   rl78_propogate_register_origins ();
2667   rl78_calculate_death_notes ();
2668
2669   if (dump_file)
2670     {
2671       fprintf (dump_file, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n");
2672       print_rtl_with_bb (dump_file, get_insns ());
2673       fprintf (dump_file, "\n======================================================================\n");
2674     }
2675
2676   rl78_remove_unused_sets ();
2677
2678   /* The code after devirtualizing has changed so much that at this point
2679      we might as well just rescan everything.  Note that
2680      df_rescan_all_insns is not going to help here because it does not
2681      touch the artificial uses and defs.  */
2682   df_finish_pass (true);
2683   if (optimize > 1)
2684     df_live_add_problem ();
2685   df_scan_alloc (NULL);
2686   df_scan_blocks ();
2687
2688   if (optimize)
2689     df_analyze ();
2690 }
2691
2692 #undef TARGET_RETURN_IN_MEMORY
2693 #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory
2694
2695 static bool
2696 rl78_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2697 {
2698   const HOST_WIDE_INT size = int_size_in_bytes (type);
2699   return (size == -1 || size > 8);
2700 }
2701
2702 \f
2703 struct gcc_target targetm = TARGET_INITIALIZER;
2704
2705 #include "gt-rl78.h"