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