1 /* Subroutines used for code generation on Renesas RL78 processors.
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
27 #include "stor-layout.h"
31 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
35 #include "insn-attr.h"
47 #include "diagnostic-core.h"
50 #include "dominance.h"
56 #include "cfgcleanup.h"
58 #include "basic-block.h"
64 #include "target-def.h"
65 #include "langhooks.h"
66 #include "rl78-protos.h"
68 #include "tree-pass.h"
70 #include "tm-constrs.h" /* for satisfies_constraint_*(). */
71 #include "insn-flags.h" /* for gen_*(). */
74 static inline bool is_interrupt_func (const_tree decl
);
75 static inline bool is_brk_interrupt_func (const_tree decl
);
76 static void rl78_reorg (void);
79 /* Debugging statements are tagged with DEBUG0 only so that they can
80 be easily enabled individually, by replacing the '0' with '1' as
85 /* REGISTER_NAMES has the names for individual 8-bit registers, but
86 these have the names we need to use when referring to 16-bit
88 static const char * const word_regnames
[] =
90 "ax", "AX", "bc", "BC", "de", "DE", "hl", "HL",
91 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
92 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
93 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
94 "sp", "ap", "psw", "es", "cs"
97 struct GTY(()) machine_function
99 /* If set, the rest of the fields have been computed. */
101 /* Which register pairs need to be pushed in the prologue. */
102 int need_to_push
[FIRST_PSEUDO_REGISTER
/ 2];
104 /* These fields describe the frame layout... */
106 /* 4 bytes for saved PC */
109 int framesize_locals
;
110 int framesize_outgoing
;
114 /* If set, recog is allowed to match against the "real" patterns. */
116 /* If set, recog is allowed to match against the "virtual" patterns. */
118 /* Set if the current function needs to clean up any trampolines. */
119 int trampolines_used
;
122 /* This is our init_machine_status, as set in
123 rl78_option_override. */
124 static struct machine_function
*
125 rl78_init_machine_status (void)
127 struct machine_function
*m
;
129 m
= ggc_cleared_alloc
<machine_function
> ();
130 m
->virt_insns_ok
= 1;
135 /* This pass converts virtual instructions using virtual registers, to
136 real instructions using real registers. Rather than run it as
137 reorg, we reschedule it before vartrack to help with debugging. */
140 const pass_data pass_data_rl78_devirt
=
144 OPTGROUP_NONE
, /* optinfo_flags */
145 TV_MACH_DEP
, /* tv_id */
146 0, /* properties_required */
147 0, /* properties_provided */
148 0, /* properties_destroyed */
149 0, /* todo_flags_start */
150 0, /* todo_flags_finish */
153 class pass_rl78_devirt
: public rtl_opt_pass
156 pass_rl78_devirt(gcc::context
*ctxt
)
157 : rtl_opt_pass(pass_data_rl78_devirt
, ctxt
)
161 /* opt_pass methods: */
162 virtual unsigned int execute (function
*)
173 make_pass_rl78_devirt (gcc::context
*ctxt
)
175 return new pass_rl78_devirt (ctxt
);
178 /* Redundant move elimination pass. Must be run after the basic block
179 reordering pass for the best effect. */
182 move_elim_pass (void)
184 rtx_insn
*insn
, *ninsn
;
187 for (insn
= get_insns (); insn
; insn
= ninsn
)
191 ninsn
= next_nonnote_nondebug_insn (insn
);
193 if ((set
= single_set (insn
)) == NULL_RTX
)
199 /* If we have two SET insns in a row (without anything
200 between them) and the source of the second one is the
201 destination of the first one, and vice versa, then we
202 can eliminate the second SET. */
204 && rtx_equal_p (SET_DEST (prev
), SET_SRC (set
))
205 && rtx_equal_p (SET_DEST (set
), SET_SRC (prev
))
209 fprintf (dump_file
, " Delete insn %d because it is redundant\n",
220 print_rtl_with_bb (dump_file
, get_insns (), 0);
227 const pass_data pass_data_rl78_move_elim
=
230 "move_elim", /* name */
231 OPTGROUP_NONE
, /* optinfo_flags */
232 TV_MACH_DEP
, /* tv_id */
233 0, /* properties_required */
234 0, /* properties_provided */
235 0, /* properties_destroyed */
236 0, /* todo_flags_start */
237 0, /* todo_flags_finish */
240 class pass_rl78_move_elim
: public rtl_opt_pass
243 pass_rl78_move_elim(gcc::context
*ctxt
)
244 : rtl_opt_pass(pass_data_rl78_move_elim
, ctxt
)
248 /* opt_pass methods: */
249 virtual unsigned int execute (function
*) { return move_elim_pass (); }
255 make_pass_rl78_move_elim (gcc::context
*ctxt
)
257 return new pass_rl78_move_elim (ctxt
);
260 #undef TARGET_ASM_FILE_START
261 #define TARGET_ASM_FILE_START rl78_asm_file_start
264 rl78_asm_file_start (void)
270 /* The memory used is 0xffec8 to 0xffedf; real registers are in
271 0xffee0 to 0xffee7. */
272 for (i
= 8; i
< 32; i
++)
273 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", i
, 0xffec0 + i
);
277 for (i
= 0; i
< 8; i
++)
279 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", 8 + i
, 0xffef0 + i
);
280 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", 16 + i
, 0xffee8 + i
);
281 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", 24 + i
, 0xffee0 + i
);
285 opt_pass
*rl78_devirt_pass
= make_pass_rl78_devirt (g
);
286 static struct register_pass_info rl78_devirt_info
=
291 PASS_POS_INSERT_BEFORE
294 opt_pass
*rl78_move_elim_pass
= make_pass_rl78_move_elim (g
);
295 static struct register_pass_info rl78_move_elim_info
=
300 PASS_POS_INSERT_AFTER
303 register_pass (& rl78_devirt_info
);
304 register_pass (& rl78_move_elim_info
);
308 #undef TARGET_OPTION_OVERRIDE
309 #define TARGET_OPTION_OVERRIDE rl78_option_override
312 rl78_option_override (void)
314 flag_omit_frame_pointer
= 1;
315 flag_no_function_cse
= 1;
316 flag_split_wide_types
= 0;
318 init_machine_status
= rl78_init_machine_status
;
324 for (i
= 24; i
< 32; i
++)
329 /* Most registers are 8 bits. Some are 16 bits because, for example,
330 gcc doesn't like dealing with $FP as a register pair (the second
331 half of $fp is also 2 to keep reload happy wrt register pairs, but
332 no register class includes it). This table maps register numbers
334 static const int register_sizes
[] =
336 1, 1, 1, 1, 1, 1, 1, 1,
337 1, 1, 1, 1, 1, 1, 1, 1,
338 1, 1, 1, 1, 1, 1, 2, 2,
339 1, 1, 1, 1, 1, 1, 1, 1,
343 /* Predicates used in the MD patterns. This one is true when virtual
344 insns may be matched, which typically means before (or during) the
347 rl78_virt_insns_ok (void)
350 return cfun
->machine
->virt_insns_ok
;
354 /* Predicates used in the MD patterns. This one is true when real
355 insns may be matched, which typically means after (or during) the
358 rl78_real_insns_ok (void)
361 return cfun
->machine
->real_insns_ok
;
365 /* Implements HARD_REGNO_NREGS. */
367 rl78_hard_regno_nregs (int regno
, machine_mode mode
)
369 int rs
= register_sizes
[regno
];
372 return ((GET_MODE_SIZE (mode
) + rs
- 1) / rs
);
375 /* Implements HARD_REGNO_MODE_OK. */
377 rl78_hard_regno_mode_ok (int regno
, machine_mode mode
)
379 int s
= GET_MODE_SIZE (mode
);
383 /* These are not to be used by gcc. */
384 if (regno
== 23 || regno
== ES_REG
|| regno
== CS_REG
)
386 /* $fp can always be accessed as a 16-bit value. */
387 if (regno
== FP_REG
&& s
== 2)
391 /* Since a reg-reg move is really a reg-mem move, we must
392 enforce alignment. */
393 if (s
> 1 && (regno
% 2))
398 return (mode
== BImode
);
399 /* All other registers must be accessed in their natural sizes. */
400 if (s
== register_sizes
[regno
])
405 /* Simplify_gen_subreg() doesn't handle memory references the way we
406 need it to below, so we use this function for when we must get a
407 valid subreg in a "natural" state. */
409 rl78_subreg (machine_mode mode
, rtx r
, machine_mode omode
, int byte
)
411 if (GET_CODE (r
) == MEM
)
412 return adjust_address (r
, mode
, byte
);
414 return simplify_gen_subreg (mode
, r
, omode
, byte
);
417 /* Used by movsi. Split SImode moves into two HImode moves, using
418 appropriate patterns for the upper and lower halves of symbols. */
420 rl78_expand_movsi (rtx
*operands
)
422 rtx op00
, op02
, op10
, op12
;
424 op00
= rl78_subreg (HImode
, operands
[0], SImode
, 0);
425 op02
= rl78_subreg (HImode
, operands
[0], SImode
, 2);
426 if (GET_CODE (operands
[1]) == CONST
427 || GET_CODE (operands
[1]) == SYMBOL_REF
)
429 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (0));
430 op10
= gen_rtx_CONST (HImode
, op10
);
431 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (16));
432 op12
= gen_rtx_CONST (HImode
, op12
);
436 op10
= rl78_subreg (HImode
, operands
[1], SImode
, 0);
437 op12
= rl78_subreg (HImode
, operands
[1], SImode
, 2);
440 if (rtx_equal_p (operands
[0], operands
[1]))
442 else if (rtx_equal_p (op00
, op12
))
444 emit_move_insn (op02
, op12
);
445 emit_move_insn (op00
, op10
);
449 emit_move_insn (op00
, op10
);
450 emit_move_insn (op02
, op12
);
454 /* Generate code to move an SImode value. */
456 rl78_split_movsi (rtx
*operands
)
458 rtx op00
, op02
, op10
, op12
;
460 op00
= rl78_subreg (HImode
, operands
[0], SImode
, 0);
461 op02
= rl78_subreg (HImode
, operands
[0], SImode
, 2);
463 if (GET_CODE (operands
[1]) == CONST
464 || GET_CODE (operands
[1]) == SYMBOL_REF
)
466 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (0));
467 op10
= gen_rtx_CONST (HImode
, op10
);
468 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (16));
469 op12
= gen_rtx_CONST (HImode
, op12
);
473 op10
= rl78_subreg (HImode
, operands
[1], SImode
, 0);
474 op12
= rl78_subreg (HImode
, operands
[1], SImode
, 2);
477 if (rtx_equal_p (operands
[0], operands
[1]))
479 else if (rtx_equal_p (op00
, op12
))
495 /* Used by various two-operand expanders which cannot accept all
496 operands in the "far" namespace. Force some such operands into
497 registers so that each pattern has at most one far operand. */
499 rl78_force_nonfar_2 (rtx
*operands
, rtx (*gen
)(rtx
,rtx
))
504 /* FIXME: in the future, be smarter about only doing this if the
505 other operand is also far, assuming the devirtualizer can also
507 if (rl78_far_p (operands
[0]))
509 temp_reg
= operands
[0];
510 operands
[0] = gen_reg_rtx (GET_MODE (operands
[0]));
516 emit_insn (gen (operands
[0], operands
[1]));
518 emit_move_insn (temp_reg
, operands
[0]);
522 /* Likewise, but for three-operand expanders. */
524 rl78_force_nonfar_3 (rtx
*operands
, rtx (*gen
)(rtx
,rtx
,rtx
))
529 /* FIXME: Likewise. */
530 if (rl78_far_p (operands
[1]))
532 rtx temp_reg
= gen_reg_rtx (GET_MODE (operands
[1]));
533 emit_move_insn (temp_reg
, operands
[1]);
534 operands
[1] = temp_reg
;
537 if (rl78_far_p (operands
[0]))
539 temp_reg
= operands
[0];
540 operands
[0] = gen_reg_rtx (GET_MODE (operands
[0]));
546 emit_insn (gen (operands
[0], operands
[1], operands
[2]));
548 emit_move_insn (temp_reg
, operands
[0]);
552 #undef TARGET_CAN_ELIMINATE
553 #define TARGET_CAN_ELIMINATE rl78_can_eliminate
556 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to ATTRIBUTE_UNUSED
)
561 /* Returns true if the given register needs to be saved by the
564 need_to_save (unsigned int regno
)
566 if (is_interrupt_func (cfun
->decl
))
568 /* We don't know what devirt will need */
572 /* We don't need to save registers that have
573 been reserved for interrupt handlers. */
577 /* If the handler is a non-leaf function then it may call
578 non-interrupt aware routines which will happily clobber
579 any call_used registers, so we have to preserve them. */
580 if (!crtl
->is_leaf
&& call_used_regs
[regno
])
583 /* Otherwise we only have to save a register, call_used
584 or not, if it is used by this handler. */
585 return df_regs_ever_live_p (regno
);
588 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
590 if (fixed_regs
[regno
])
592 if (crtl
->calls_eh_return
)
594 if (df_regs_ever_live_p (regno
)
595 && !call_used_regs
[regno
])
600 /* We use this to wrap all emitted insns in the prologue. */
604 RTX_FRAME_RELATED_P (x
) = 1;
608 /* Compute all the frame-related fields in our machine_function
611 rl78_compute_frame_info (void)
615 cfun
->machine
->computed
= 1;
616 cfun
->machine
->framesize_regs
= 0;
617 cfun
->machine
->framesize_locals
= get_frame_size ();
618 cfun
->machine
->framesize_outgoing
= crtl
->outgoing_args_size
;
620 for (i
= 0; i
< 16; i
++)
621 if (need_to_save (i
* 2) || need_to_save (i
* 2 + 1))
623 cfun
->machine
->need_to_push
[i
] = 1;
624 cfun
->machine
->framesize_regs
+= 2;
627 cfun
->machine
->need_to_push
[i
] = 0;
629 if ((cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
) & 1)
630 cfun
->machine
->framesize_locals
++;
632 cfun
->machine
->framesize
= (cfun
->machine
->framesize_regs
633 + cfun
->machine
->framesize_locals
634 + cfun
->machine
->framesize_outgoing
);
637 /* Returns true if the provided function has the specified attribute. */
639 has_func_attr (const_tree decl
, const char * func_attr
)
641 if (decl
== NULL_TREE
)
642 decl
= current_function_decl
;
644 return lookup_attribute (func_attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
647 /* Returns true if the provided function has the "interrupt" attribute. */
649 is_interrupt_func (const_tree decl
)
651 return has_func_attr (decl
, "interrupt") || has_func_attr (decl
, "brk_interrupt");
654 /* Returns true if the provided function has the "brk_interrupt" attribute. */
656 is_brk_interrupt_func (const_tree decl
)
658 return has_func_attr (decl
, "brk_interrupt");
661 /* Check "interrupt" attributes. */
663 rl78_handle_func_attribute (tree
* node
,
666 int flags ATTRIBUTE_UNUSED
,
669 gcc_assert (DECL_P (* node
));
670 gcc_assert (args
== NULL_TREE
);
672 if (TREE_CODE (* node
) != FUNCTION_DECL
)
674 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
676 * no_add_attrs
= true;
679 /* FIXME: We ought to check that the interrupt and exception
680 handler attributes have been applied to void functions. */
684 #undef TARGET_ATTRIBUTE_TABLE
685 #define TARGET_ATTRIBUTE_TABLE rl78_attribute_table
687 /* Table of RL78-specific attributes. */
688 const struct attribute_spec rl78_attribute_table
[] =
690 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
691 affects_type_identity. */
692 { "interrupt", 0, 0, true, false, false, rl78_handle_func_attribute
,
694 { "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute
,
696 { "naked", 0, 0, true, false, false, rl78_handle_func_attribute
,
698 { NULL
, 0, 0, false, false, false, NULL
, false }
703 /* Break down an address RTX into its component base/index/addend
704 portions and return TRUE if the address is of a valid form, else
707 characterize_address (rtx x
, rtx
*base
, rtx
*index
, rtx
*addend
)
713 if (GET_CODE (x
) == UNSPEC
714 && XINT (x
, 1) == UNS_ES_ADDR
)
715 x
= XVECEXP (x
, 0, 1);
717 if (GET_CODE (x
) == REG
)
723 /* We sometimes get these without the CONST wrapper */
724 if (GET_CODE (x
) == PLUS
725 && GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
726 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
732 if (GET_CODE (x
) == PLUS
)
737 if (GET_CODE (*base
) != REG
738 && GET_CODE (x
) == REG
)
745 if (GET_CODE (*base
) != REG
)
748 if (GET_CODE (x
) == ZERO_EXTEND
749 && GET_CODE (XEXP (x
, 0)) == REG
)
751 *index
= XEXP (x
, 0);
756 switch (GET_CODE (x
))
759 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
760 && GET_CODE (XEXP (x
, 0)) == CONST_INT
)
783 /* Used by the Whb constraint. Match addresses that use HL+B or HL+C
786 rl78_hl_b_c_addr_p (rtx op
)
790 if (GET_CODE (op
) != PLUS
)
794 if (GET_CODE (hl
) == ZERO_EXTEND
)
800 if (GET_CODE (hl
) != REG
)
802 if (GET_CODE (bc
) != ZERO_EXTEND
)
805 if (GET_CODE (bc
) != REG
)
807 if (REGNO (hl
) != HL_REG
)
809 if (REGNO (bc
) != B_REG
&& REGNO (bc
) != C_REG
)
815 #define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
817 /* Used in various constraints and predicates to match operands in the
818 "far" address space. */
825 fprintf (stderr
, "\033[35mrl78_far_p: "); debug_rtx (x
);
826 fprintf (stderr
, " = %d\033[0m\n", MEM_ADDR_SPACE (x
) == ADDR_SPACE_FAR
);
828 return MEM_ADDR_SPACE (x
) == ADDR_SPACE_FAR
;
831 /* Return the appropriate mode for a named address pointer. */
832 #undef TARGET_ADDR_SPACE_POINTER_MODE
833 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
835 rl78_addr_space_pointer_mode (addr_space_t addrspace
)
839 case ADDR_SPACE_GENERIC
:
848 /* Returns TRUE for valid addresses. */
849 #undef TARGET_VALID_POINTER_MODE
850 #define TARGET_VALID_POINTER_MODE rl78_valid_pointer_mode
852 rl78_valid_pointer_mode (machine_mode m
)
854 return (m
== HImode
|| m
== SImode
);
857 /* Return the appropriate mode for a named address address. */
858 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
859 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
861 rl78_addr_space_address_mode (addr_space_t addrspace
)
865 case ADDR_SPACE_GENERIC
:
874 #undef TARGET_LEGITIMATE_CONSTANT_P
875 #define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant
878 rl78_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED
, rtx x ATTRIBUTE_UNUSED
)
883 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
884 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P rl78_as_legitimate_address
887 rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
,
888 bool strict ATTRIBUTE_UNUSED
, addr_space_t as ATTRIBUTE_UNUSED
)
890 rtx base
, index
, addend
;
891 bool is_far_addr
= false;
893 if (GET_CODE (x
) == UNSPEC
894 && XINT (x
, 1) == UNS_ES_ADDR
)
896 x
= XVECEXP (x
, 0, 1);
900 if (as
== ADDR_SPACE_GENERIC
901 && (GET_MODE (x
) == SImode
|| is_far_addr
))
904 if (! characterize_address (x
, &base
, &index
, &addend
))
907 /* We can't extract the high/low portions of a PLUS address
908 involving a register during devirtualization, so make sure all
909 such __far addresses do not have addends. This forces GCC to do
910 the sum separately. */
911 if (addend
&& base
&& as
== ADDR_SPACE_FAR
)
916 int ir
= REGNO (index
);
917 int br
= REGNO (base
);
919 #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
920 OK (REG_IS (br
, HL_REG
) && REG_IS (ir
, B_REG
), "[hl+b]");
921 OK (REG_IS (br
, HL_REG
) && REG_IS (ir
, C_REG
), "[hl+c]");
925 if (strict
&& base
&& GET_CODE (base
) == REG
&& REGNO (base
) >= FIRST_PSEUDO_REGISTER
)
928 if (! cfun
->machine
->virt_insns_ok
&& base
&& GET_CODE (base
) == REG
929 && REGNO (base
) >= 8 && REGNO (base
) <= 31)
935 /* Determine if one named address space is a subset of another. */
936 #undef TARGET_ADDR_SPACE_SUBSET_P
937 #define TARGET_ADDR_SPACE_SUBSET_P rl78_addr_space_subset_p
939 rl78_addr_space_subset_p (addr_space_t subset
, addr_space_t superset
)
941 gcc_assert (subset
== ADDR_SPACE_GENERIC
|| subset
== ADDR_SPACE_FAR
);
942 gcc_assert (superset
== ADDR_SPACE_GENERIC
|| superset
== ADDR_SPACE_FAR
);
944 if (subset
== superset
)
948 return (subset
== ADDR_SPACE_GENERIC
&& superset
== ADDR_SPACE_FAR
);
951 #undef TARGET_ADDR_SPACE_CONVERT
952 #define TARGET_ADDR_SPACE_CONVERT rl78_addr_space_convert
953 /* Convert from one address space to another. */
955 rl78_addr_space_convert (rtx op
, tree from_type
, tree to_type
)
957 addr_space_t from_as
= TYPE_ADDR_SPACE (TREE_TYPE (from_type
));
958 addr_space_t to_as
= TYPE_ADDR_SPACE (TREE_TYPE (to_type
));
961 gcc_assert (from_as
== ADDR_SPACE_GENERIC
|| from_as
== ADDR_SPACE_FAR
);
962 gcc_assert (to_as
== ADDR_SPACE_GENERIC
|| to_as
== ADDR_SPACE_FAR
);
964 if (to_as
== ADDR_SPACE_GENERIC
&& from_as
== ADDR_SPACE_FAR
)
966 /* This is unpredictable, as we're truncating off usable address
969 result
= gen_reg_rtx (HImode
);
970 emit_move_insn (result
, simplify_subreg (HImode
, op
, SImode
, 0));
973 else if (to_as
== ADDR_SPACE_FAR
&& from_as
== ADDR_SPACE_GENERIC
)
975 /* This always works. */
976 result
= gen_reg_rtx (SImode
);
977 emit_move_insn (rl78_subreg (HImode
, result
, SImode
, 0), op
);
978 emit_move_insn (rl78_subreg (HImode
, result
, SImode
, 2), const0_rtx
);
985 /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */
987 rl78_regno_mode_code_ok_for_base_p (int regno
, machine_mode mode ATTRIBUTE_UNUSED
,
988 addr_space_t address_space ATTRIBUTE_UNUSED
,
989 int outer_code ATTRIBUTE_UNUSED
, int index_code
)
991 if (regno
<= SP_REG
&& regno
>= 16)
993 if (index_code
== REG
)
994 return (regno
== HL_REG
);
995 if (regno
== C_REG
|| regno
== B_REG
|| regno
== E_REG
|| regno
== L_REG
)
1000 /* Implements MODE_CODE_BASE_REG_CLASS. */
1002 rl78_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED
,
1003 addr_space_t address_space ATTRIBUTE_UNUSED
,
1004 int outer_code ATTRIBUTE_UNUSED
,
1005 int index_code ATTRIBUTE_UNUSED
)
1010 /* Implements INITIAL_ELIMINATION_OFFSET. The frame layout is
1011 described in the machine_Function struct definition, above. */
1013 rl78_initial_elimination_offset (int from
, int to
)
1015 int rv
= 0; /* as if arg to arg */
1017 rl78_compute_frame_info ();
1021 case STACK_POINTER_REGNUM
:
1022 rv
+= cfun
->machine
->framesize_outgoing
;
1023 rv
+= cfun
->machine
->framesize_locals
;
1025 case FRAME_POINTER_REGNUM
:
1026 rv
+= cfun
->machine
->framesize_regs
;
1035 case FRAME_POINTER_REGNUM
:
1037 rv
-= cfun
->machine
->framesize_regs
;
1038 case ARG_POINTER_REGNUM
:
1048 rl78_is_naked_func (void)
1050 return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
)) != NULL_TREE
);
1053 /* Expand the function prologue (from the prologue pattern). */
1055 rl78_expand_prologue (void)
1058 rtx sp
= gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
);
1061 if (rl78_is_naked_func ())
1064 /* Always re-compute the frame info - the register usage may have changed. */
1065 rl78_compute_frame_info ();
1067 if (flag_stack_usage_info
)
1068 current_function_static_stack_size
= cfun
->machine
->framesize
;
1070 if (is_interrupt_func (cfun
->decl
) && !TARGET_G10
)
1071 for (i
= 0; i
< 4; i
++)
1072 if (cfun
->machine
->need_to_push
[i
])
1074 /* Select Bank 0 if we are using any registers from Bank 0. */
1075 emit_insn (gen_sel_rb (GEN_INT (0)));
1079 for (i
= 0; i
< 16; i
++)
1080 if (cfun
->machine
->need_to_push
[i
])
1084 emit_move_insn (gen_rtx_REG (HImode
, 0), gen_rtx_REG (HImode
, i
*2));
1085 F (emit_insn (gen_push (gen_rtx_REG (HImode
, 0))));
1089 int need_bank
= i
/4;
1091 if (need_bank
!= rb
)
1093 emit_insn (gen_sel_rb (GEN_INT (need_bank
)));
1096 F (emit_insn (gen_push (gen_rtx_REG (HImode
, i
*2))));
1101 emit_insn (gen_sel_rb (GEN_INT (0)));
1103 if (frame_pointer_needed
)
1105 F (emit_move_insn (gen_rtx_REG (HImode
, AX_REG
),
1106 gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
)));
1107 F (emit_move_insn (gen_rtx_REG (HImode
, FRAME_POINTER_REGNUM
),
1108 gen_rtx_REG (HImode
, AX_REG
)));
1111 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
1114 int fs_byte
= (fs
> 254) ? 254 : fs
;
1115 F (emit_insn (gen_subhi3 (sp
, sp
, GEN_INT (fs_byte
))));
1120 /* Expand the function epilogue (from the epilogue pattern). */
1122 rl78_expand_epilogue (void)
1125 rtx sp
= gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
);
1128 if (rl78_is_naked_func ())
1131 if (frame_pointer_needed
)
1133 emit_move_insn (gen_rtx_REG (HImode
, AX_REG
),
1134 gen_rtx_REG (HImode
, FRAME_POINTER_REGNUM
));
1135 emit_move_insn (gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
),
1136 gen_rtx_REG (HImode
, AX_REG
));
1140 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
1143 int fs_byte
= (fs
> 254) ? 254 : fs
;
1145 emit_insn (gen_addhi3 (sp
, sp
, GEN_INT (fs_byte
)));
1150 for (i
= 15; i
>= 0; i
--)
1151 if (cfun
->machine
->need_to_push
[i
])
1153 rtx dest
= gen_rtx_REG (HImode
, i
* 2);
1157 rtx ax
= gen_rtx_REG (HImode
, 0);
1159 emit_insn (gen_pop (ax
));
1162 emit_move_insn (dest
, ax
);
1163 /* Generate a USE of the pop'd register so that DCE will not eliminate the move. */
1164 emit_insn (gen_use (dest
));
1169 int need_bank
= i
/ 4;
1171 if (need_bank
!= rb
)
1173 emit_insn (gen_sel_rb (GEN_INT (need_bank
)));
1176 emit_insn (gen_pop (dest
));
1181 emit_insn (gen_sel_rb (GEN_INT (0)));
1183 if (cfun
->machine
->trampolines_used
)
1184 emit_insn (gen_trampoline_uninit ());
1186 if (is_brk_interrupt_func (cfun
->decl
))
1187 emit_jump_insn (gen_brk_interrupt_return ());
1188 else if (is_interrupt_func (cfun
->decl
))
1189 emit_jump_insn (gen_interrupt_return ());
1191 emit_jump_insn (gen_rl78_return ());
1194 /* Likewise, for exception handlers. */
1196 rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED
)
1198 /* FIXME - replace this with an indirect jump with stack adjust. */
1199 emit_jump_insn (gen_rl78_return ());
1202 #undef TARGET_ASM_FUNCTION_PROLOGUE
1203 #define TARGET_ASM_FUNCTION_PROLOGUE rl78_start_function
1205 /* We don't use this to actually emit the function prologue. We use
1206 this to insert a comment in the asm file describing the
1209 rl78_start_function (FILE *file
, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED
)
1213 if (cfun
->machine
->framesize
== 0)
1215 fprintf (file
, "\t; start of function\n");
1217 if (cfun
->machine
->framesize_regs
)
1219 fprintf (file
, "\t; push %d:", cfun
->machine
->framesize_regs
);
1220 for (i
= 0; i
< 16; i
++)
1221 if (cfun
->machine
->need_to_push
[i
])
1222 fprintf (file
, " %s", word_regnames
[i
*2]);
1223 fprintf (file
, "\n");
1226 if (frame_pointer_needed
)
1227 fprintf (file
, "\t; $fp points here (r22)\n");
1229 if (cfun
->machine
->framesize_locals
)
1230 fprintf (file
, "\t; locals: %d byte%s\n", cfun
->machine
->framesize_locals
,
1231 cfun
->machine
->framesize_locals
== 1 ? "" : "s");
1233 if (cfun
->machine
->framesize_outgoing
)
1234 fprintf (file
, "\t; outgoing: %d byte%s\n", cfun
->machine
->framesize_outgoing
,
1235 cfun
->machine
->framesize_outgoing
== 1 ? "" : "s");
1238 /* Return an RTL describing where a function return value of type RET_TYPE
1241 #undef TARGET_FUNCTION_VALUE
1242 #define TARGET_FUNCTION_VALUE rl78_function_value
1245 rl78_function_value (const_tree ret_type
,
1246 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1247 bool outgoing ATTRIBUTE_UNUSED
)
1249 machine_mode mode
= TYPE_MODE (ret_type
);
1251 return gen_rtx_REG (mode
, 8);
1254 #undef TARGET_PROMOTE_FUNCTION_MODE
1255 #define TARGET_PROMOTE_FUNCTION_MODE rl78_promote_function_mode
1258 rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
1260 int *punsignedp ATTRIBUTE_UNUSED
,
1261 const_tree funtype ATTRIBUTE_UNUSED
, int for_return ATTRIBUTE_UNUSED
)
1266 /* Return an RTL expression describing the register holding a function
1267 parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
1268 be passed on the stack. CUM describes the previous parameters to the
1269 function and NAMED is false if the parameter is part of a variable
1270 parameter list, or the last named parameter before the start of a
1271 variable parameter list. */
1273 #undef TARGET_FUNCTION_ARG
1274 #define TARGET_FUNCTION_ARG rl78_function_arg
1277 rl78_function_arg (cumulative_args_t cum_v ATTRIBUTE_UNUSED
,
1278 machine_mode mode ATTRIBUTE_UNUSED
,
1279 const_tree type ATTRIBUTE_UNUSED
,
1280 bool named ATTRIBUTE_UNUSED
)
1285 #undef TARGET_FUNCTION_ARG_ADVANCE
1286 #define TARGET_FUNCTION_ARG_ADVANCE rl78_function_arg_advance
1289 rl78_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
, const_tree type
,
1290 bool named ATTRIBUTE_UNUSED
)
1293 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
1295 rounded_size
= ((mode
== BLKmode
)
1296 ? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
));
1297 if (rounded_size
& 1)
1299 (*cum
) += rounded_size
;
1302 #undef TARGET_FUNCTION_ARG_BOUNDARY
1303 #define TARGET_FUNCTION_ARG_BOUNDARY rl78_function_arg_boundary
1306 rl78_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED
,
1307 const_tree type ATTRIBUTE_UNUSED
)
1312 /* Supported modifier letters:
1314 A - address of a MEM
1315 S - SADDR form of a real register
1316 v - real register corresponding to a virtual register
1317 m - minus - negative of CONST_INT value.
1318 C - inverse of a conditional (NE vs EQ for example)
1319 C - complement of an integer
1320 z - collapsed conditional
1321 s - shift count mod 8
1322 S - shift count mod 16
1323 r - reverse shift count (8-(count mod 8))
1326 h - bottom HI of an SI
1328 q - bottom QI of an HI
1330 e - third QI of an SI (i.e. where the ES register gets values from)
1331 E - fourth QI of an SI (i.e. MSB)
1335 /* Implements the bulk of rl78_print_operand, below. We do it this
1336 way because we need to test for a constant at the top level and
1337 insert the '#', but not test for it anywhere else as we recurse
1338 down into the operand. */
1340 rl78_print_operand_1 (FILE * file
, rtx op
, int letter
)
1344 switch (GET_CODE (op
))
1348 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1351 if (rl78_far_p (op
))
1353 fprintf (file
, "es:");
1354 op
= gen_rtx_MEM (GET_MODE (op
), XVECEXP (XEXP (op
, 0), 0, 1));
1358 op
= adjust_address (op
, HImode
, 2);
1363 op
= adjust_address (op
, HImode
, 0);
1368 op
= adjust_address (op
, QImode
, 1);
1373 op
= adjust_address (op
, QImode
, 0);
1378 op
= adjust_address (op
, QImode
, 2);
1383 op
= adjust_address (op
, QImode
, 3);
1386 if (CONSTANT_P (XEXP (op
, 0)))
1388 fprintf (file
, "!");
1389 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1391 else if (GET_CODE (XEXP (op
, 0)) == PLUS
1392 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == SYMBOL_REF
)
1394 fprintf (file
, "!");
1395 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1397 else if (GET_CODE (XEXP (op
, 0)) == PLUS
1398 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == REG
1399 && REGNO (XEXP (XEXP (op
, 0), 0)) == 2)
1401 rl78_print_operand_1 (file
, XEXP (XEXP (op
, 0), 1), 'u');
1402 fprintf (file
, "[");
1403 rl78_print_operand_1 (file
, XEXP (XEXP (op
, 0), 0), 0);
1404 fprintf (file
, "]");
1408 fprintf (file
, "[");
1409 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1410 fprintf (file
, "]");
1417 fprintf (file
, "%s", reg_names
[REGNO (op
) | 1]);
1418 else if (letter
== 'H')
1419 fprintf (file
, "%s", reg_names
[REGNO (op
) + 2]);
1420 else if (letter
== 'q')
1421 fprintf (file
, "%s", reg_names
[REGNO (op
) & ~1]);
1422 else if (letter
== 'e')
1423 fprintf (file
, "%s", reg_names
[REGNO (op
) + 2]);
1424 else if (letter
== 'E')
1425 fprintf (file
, "%s", reg_names
[REGNO (op
) + 3]);
1426 else if (letter
== 'S')
1427 fprintf (file
, "0x%x", 0xffef8 + REGNO (op
));
1428 else if (GET_MODE (op
) == HImode
1429 && ! (REGNO (op
) & ~0xfe))
1432 fprintf (file
, "%s", word_regnames
[REGNO (op
) % 8]);
1434 fprintf (file
, "%s", word_regnames
[REGNO (op
)]);
1437 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
1442 fprintf (file
, "%ld", INTVAL (op
) >> 8);
1443 else if (letter
== 'H')
1444 fprintf (file
, "%ld", INTVAL (op
) >> 16);
1445 else if (letter
== 'q')
1446 fprintf (file
, "%ld", INTVAL (op
) & 0xff);
1447 else if (letter
== 'h')
1448 fprintf (file
, "%ld", INTVAL (op
) & 0xffff);
1449 else if (letter
== 'e')
1450 fprintf (file
, "%ld", (INTVAL (op
) >> 16) & 0xff);
1451 else if (letter
== 'B')
1452 fprintf (file
, "%d", exact_log2 (INTVAL (op
)));
1453 else if (letter
== 'E')
1454 fprintf (file
, "%ld", (INTVAL (op
) >> 24) & 0xff);
1455 else if (letter
== 'm')
1456 fprintf (file
, "%ld", - INTVAL (op
));
1457 else if (letter
== 's')
1458 fprintf (file
, "%ld", INTVAL (op
) % 8);
1459 else if (letter
== 'S')
1460 fprintf (file
, "%ld", INTVAL (op
) % 16);
1461 else if (letter
== 'r')
1462 fprintf (file
, "%ld", 8 - (INTVAL (op
) % 8));
1463 else if (letter
== 'C')
1464 fprintf (file
, "%ld", (INTVAL (op
) ^ 0x8000) & 0xffff);
1466 fprintf (file
, "%ld", INTVAL (op
));
1470 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1475 int bits
= INTVAL (XEXP (op
, 1));
1476 int ofs
= INTVAL (XEXP (op
, 2));
1477 if (bits
== 16 && ofs
== 0)
1478 fprintf (file
, "%%lo16(");
1479 else if (bits
== 16 && ofs
== 16)
1480 fprintf (file
, "%%hi16(");
1481 else if (bits
== 8 && ofs
== 16)
1482 fprintf (file
, "%%hi8(");
1485 rl78_print_operand_1 (file
, XEXP (op
, 0), 0);
1486 fprintf (file
, ")");
1491 if (GET_CODE (XEXP (op
, 0)) == REG
)
1492 fprintf (file
, "%s", reg_names
[REGNO (XEXP (op
, 0))]);
1494 print_rtl (file
, op
);
1501 fprintf (file
, "%%hi16(");
1507 fprintf (file
, "%%lo16(");
1513 fprintf (file
, "%%hi8(");
1517 if (letter
== 'q' || letter
== 'Q')
1518 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1520 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTEND
)
1522 rl78_print_operand_1 (file
, XEXP (op
, 1), letter
);
1523 fprintf (file
, "+");
1524 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1528 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1529 fprintf (file
, "+");
1530 rl78_print_operand_1 (file
, XEXP (op
, 1), letter
);
1533 fprintf (file
, ")");
1540 fprintf (file
, "%%hi16(");
1546 fprintf (file
, "%%lo16(");
1552 fprintf (file
, "%%hi8(");
1556 if (letter
== 'q' || letter
== 'Q')
1557 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1559 output_addr_const (file
, op
);
1561 fprintf (file
, ")");
1566 output_asm_label (op
);
1571 fprintf (file
, "#comparison eliminated");
1573 fprintf (file
, letter
== 'C' ? "nc" : "c");
1577 fprintf (file
, "br");
1579 fprintf (file
, letter
== 'C' ? "h" : "nh");
1583 fprintf (file
, "br");
1585 fprintf (file
, letter
== 'C' ? "c" : "nc");
1589 fprintf (file
, "#comparison eliminated");
1591 fprintf (file
, letter
== 'C' ? "nh" : "h");
1595 fprintf (file
, "br");
1597 fprintf (file
, letter
== 'C' ? "nz" : "z");
1601 fprintf (file
, "#comparison eliminated");
1603 fprintf (file
, letter
== 'C' ? "z" : "nz");
1606 /* Note: these assume appropriate adjustments were made so that
1607 unsigned comparisons, which is all this chip has, will
1611 fprintf (file
, "#comparison eliminated");
1613 fprintf (file
, letter
== 'C' ? "nc" : "c");
1617 fprintf (file
, "br");
1619 fprintf (file
, letter
== 'C' ? "h" : "nh");
1623 fprintf (file
, "br");
1625 fprintf (file
, letter
== 'C' ? "c" : "nc");
1629 fprintf (file
, "#comparison eliminated");
1631 fprintf (file
, letter
== 'C' ? "nh" : "h");
1635 fprintf (file
, "(%s)", GET_RTX_NAME (GET_CODE (op
)));
1640 #undef TARGET_PRINT_OPERAND
1641 #define TARGET_PRINT_OPERAND rl78_print_operand
1644 rl78_print_operand (FILE * file
, rtx op
, int letter
)
1646 if (CONSTANT_P (op
) && letter
!= 'u' && letter
!= 's' && letter
!= 'r' && letter
!= 'S' && letter
!= 'B')
1647 fprintf (file
, "#");
1648 rl78_print_operand_1 (file
, op
, letter
);
1651 #undef TARGET_TRAMPOLINE_INIT
1652 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
1654 /* Note that the RL78's addressing makes it very difficult to do
1655 trampolines on the stack. So, libgcc has a small pool of
1656 trampolines from which one is allocated to this task. */
1658 rl78_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
1660 rtx mov_addr
, thunk_addr
;
1661 rtx function
= XEXP (DECL_RTL (fndecl
), 0);
1663 mov_addr
= adjust_address (m_tramp
, HImode
, 0);
1664 thunk_addr
= gen_reg_rtx (HImode
);
1666 function
= force_reg (HImode
, function
);
1667 static_chain
= force_reg (HImode
, static_chain
);
1669 emit_insn (gen_trampoline_init (thunk_addr
, function
, static_chain
));
1670 emit_move_insn (mov_addr
, thunk_addr
);
1672 cfun
->machine
->trampolines_used
= 1;
1675 #undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
1676 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS rl78_trampoline_adjust_address
1679 rl78_trampoline_adjust_address (rtx m_tramp
)
1681 rtx x
= gen_rtx_MEM (HImode
, m_tramp
);
1685 /* Expander for cbranchqi4 and cbranchhi4. RL78 is missing some of
1686 the "normal" compares, specifically, it only has unsigned compares,
1687 so we must synthesize the missing ones. */
1689 rl78_expand_compare (rtx
*operands
)
1691 if (GET_CODE (operands
[2]) == MEM
)
1692 operands
[2] = copy_to_mode_reg (GET_MODE (operands
[2]), operands
[2]);
1697 /* Define this to 1 if you are debugging the peephole optimizers. */
1698 #define DEBUG_PEEP 0
1700 /* Predicate used to enable the peephole2 patterns in rl78-virt.md.
1701 The default "word" size is a byte so we can effectively use all the
1702 registers, but we want to do 16-bit moves whenever possible. This
1703 function determines when such a move is an option. */
1705 rl78_peep_movhi_p (rtx
*operands
)
1710 /* (set (op0) (op1))
1711 (set (op2) (op3)) */
1713 if (! rl78_virt_insns_ok ())
1717 fprintf (stderr
, "\033[33m");
1718 debug_rtx (operands
[0]);
1719 debug_rtx (operands
[1]);
1720 debug_rtx (operands
[2]);
1721 debug_rtx (operands
[3]);
1722 fprintf (stderr
, "\033[0m");
1725 /* You can move a constant to memory as QImode, but not HImode. */
1726 if (GET_CODE (operands
[0]) == MEM
1727 && GET_CODE (operands
[1]) != REG
)
1730 fprintf (stderr
, "no peep: move constant to memory\n");
1735 if (rtx_equal_p (operands
[0], operands
[3]))
1738 fprintf (stderr
, "no peep: overlapping\n");
1743 for (i
= 0; i
< 2; i
++)
1745 if (GET_CODE (operands
[i
]) != GET_CODE (operands
[i
+2]))
1748 fprintf (stderr
, "no peep: different codes\n");
1752 if (GET_MODE (operands
[i
]) != GET_MODE (operands
[i
+2]))
1755 fprintf (stderr
, "no peep: different modes\n");
1760 switch (GET_CODE (operands
[i
]))
1764 if (REGNO (operands
[i
]) + 1 != REGNO (operands
[i
+2])
1765 || GET_MODE (operands
[i
]) != QImode
)
1768 fprintf (stderr
, "no peep: wrong regnos %d %d %d\n",
1769 REGNO (operands
[i
]), REGNO (operands
[i
+2]),
1774 if (! rl78_hard_regno_mode_ok (REGNO (operands
[i
]), HImode
))
1777 fprintf (stderr
, "no peep: reg %d not HI\n", REGNO (operands
[i
]));
1787 if (GET_MODE (operands
[i
]) != QImode
)
1789 if (MEM_ALIGN (operands
[i
]) < 16)
1791 a
= XEXP (operands
[i
], 0);
1792 if (GET_CODE (a
) == CONST
)
1794 if (GET_CODE (a
) == PLUS
)
1796 if (GET_CODE (a
) == CONST_INT
1800 fprintf (stderr
, "no peep: misaligned mem %d\n", i
);
1801 debug_rtx (operands
[i
]);
1805 m
= adjust_address (operands
[i
], QImode
, 1);
1806 if (! rtx_equal_p (m
, operands
[i
+2]))
1809 fprintf (stderr
, "no peep: wrong mem %d\n", i
);
1811 debug_rtx (operands
[i
+2]);
1819 fprintf (stderr
, "no peep: wrong rtx %d\n", i
);
1825 fprintf (stderr
, "\033[32mpeep!\033[0m\n");
1830 /* Likewise, when a peephole is activated, this function helps compute
1831 the new operands. */
1833 rl78_setup_peep_movhi (rtx
*operands
)
1837 for (i
= 0; i
< 2; i
++)
1839 switch (GET_CODE (operands
[i
]))
1842 operands
[i
+4] = gen_rtx_REG (HImode
, REGNO (operands
[i
]));
1846 operands
[i
+4] = GEN_INT ((INTVAL (operands
[i
]) & 0xff) + ((char) INTVAL (operands
[i
+2])) * 256);
1850 operands
[i
+4] = adjust_address (operands
[i
], HImode
, 0);
1860 How Devirtualization works in the RL78 GCC port
1864 The RL78 is an 8-bit port with some 16-bit operations. It has 32
1865 bytes of register space, in four banks, memory-mapped. One bank is
1866 the "selected" bank and holds the registers used for primary
1867 operations. Since the registers are memory mapped, often you can
1868 still refer to the unselected banks via memory accesses.
1872 The GCC port uses bank 0 as the "selected" registers (A, X, BC, etc)
1873 and refers to the other banks via their memory addresses, although
1874 they're treated as regular registers internally. These "virtual"
1875 registers are R8 through R23 (bank3 is reserved for asm-based
1876 interrupt handlers).
1878 There are four machine description files:
1880 rl78.md - common register-independent patterns and definitions
1881 rl78-expand.md - expanders
1882 rl78-virt.md - patterns that match BEFORE devirtualization
1883 rl78-real.md - patterns that match AFTER devirtualization
1885 At least through register allocation and reload, gcc is told that it
1886 can do pretty much anything - but may only use the virtual registers.
1887 GCC cannot properly create the varying addressing modes that the RL78
1888 supports in an efficient way.
1890 Sometime after reload, the RL78 backend "devirtualizes" the RTL. It
1891 uses the "valloc" attribute in rl78-virt.md for determining the rules
1892 by which it will replace virtual registers with real registers (or
1893 not) and how to make up addressing modes. For example, insns tagged
1894 with "ro1" have a single read-only parameter, which may need to be
1895 moved from memory/constant/vreg to a suitable real register. As part
1896 of devirtualization, a flag is toggled, disabling the rl78-virt.md
1897 patterns and enabling the rl78-real.md patterns. The new patterns'
1898 constraints are used to determine the real registers used. NOTE:
1899 patterns in rl78-virt.md essentially ignore the constrains and rely on
1900 predicates, where the rl78-real.md ones essentially ignore the
1901 predicates and rely on the constraints.
1903 The devirtualization pass is scheduled via the pass manager (despite
1904 being called "rl78_reorg") so it can be scheduled prior to var-track
1905 (the idea is to let gdb know about the new registers). Ideally, it
1906 would be scheduled right after pro/epilogue generation, so the
1907 post-reload optimizers could operate on the real registers, but when I
1908 tried that there were some issues building the target libraries.
1910 During devirtualization, a simple register move optimizer is run. It
1911 would be better to run a full CSE/propogation pass on it though, but
1912 that has not yet been attempted.
1915 #define DEBUG_ALLOC 0
1917 #define OP(x) (*recog_data.operand_loc[x])
1919 /* This array is used to hold knowledge about the contents of the
1920 real registers (A ... H), the memory-based registers (r8 ... r31)
1921 and the first NUM_STACK_LOCS words on the stack. We use this to
1922 avoid generating redundant move instructions.
1924 A value in the range 0 .. 31 indicates register A .. r31.
1925 A value in the range 32 .. 63 indicates stack slot (value - 32).
1926 A value of NOT_KNOWN indicates that the contents of that location
1929 #define NUM_STACK_LOCS 32
1930 #define NOT_KNOWN 127
1932 static unsigned char content_memory
[32 + NUM_STACK_LOCS
];
1934 static unsigned char saved_update_index
= NOT_KNOWN
;
1935 static unsigned char saved_update_value
;
1936 static machine_mode saved_update_mode
;
1940 clear_content_memory (void)
1942 memset (content_memory
, NOT_KNOWN
, sizeof content_memory
);
1944 fprintf (dump_file
, " clear content memory\n");
1945 saved_update_index
= NOT_KNOWN
;
1948 /* Convert LOC into an index into the content_memory array.
1949 If LOC cannot be converted, return NOT_KNOWN. */
1951 static unsigned char
1952 get_content_index (rtx loc
)
1956 if (loc
== NULL_RTX
)
1961 if (REGNO (loc
) < 32)
1966 mode
= GET_MODE (loc
);
1968 if (! rl78_stack_based_mem (loc
, mode
))
1971 loc
= XEXP (loc
, 0);
1974 /* loc = MEM (SP) */
1977 /* loc = MEM (PLUS (SP, INT)). */
1978 loc
= XEXP (loc
, 1);
1980 if (INTVAL (loc
) < NUM_STACK_LOCS
)
1981 return 32 + INTVAL (loc
);
1986 /* Return a string describing content INDEX in mode MODE.
1987 WARNING: Can return a pointer to a static buffer. */
1989 get_content_name (unsigned char index
, machine_mode mode
)
1991 static char buffer
[128];
1993 if (index
== NOT_KNOWN
)
1997 sprintf (buffer
, "stack slot %d", index
- 32);
1998 else if (mode
== HImode
)
1999 sprintf (buffer
, "%s%s",
2000 reg_names
[index
+ 1], reg_names
[index
]);
2002 return reg_names
[index
];
2010 display_content_memory (FILE * file
)
2014 fprintf (file
, " Known memory contents:\n");
2016 for (i
= 0; i
< sizeof content_memory
; i
++)
2017 if (content_memory
[i
] != NOT_KNOWN
)
2019 fprintf (file
, " %s contains a copy of ", get_content_name (i
, QImode
));
2020 fprintf (file
, "%s\n", get_content_name (content_memory
[i
], QImode
));
2026 update_content (unsigned char index
, unsigned char val
, machine_mode mode
)
2030 gcc_assert (index
< sizeof content_memory
);
2032 content_memory
[index
] = val
;
2033 if (val
!= NOT_KNOWN
)
2034 content_memory
[val
] = index
;
2036 /* Make the entry in dump_file *before* VAL is increased below. */
2039 fprintf (dump_file
, " %s now contains ", get_content_name (index
, mode
));
2040 if (val
== NOT_KNOWN
)
2041 fprintf (dump_file
, "Unknown\n");
2043 fprintf (dump_file
, "%s and vice versa\n", get_content_name (val
, mode
));
2048 val
= val
== NOT_KNOWN
? val
: val
+ 1;
2050 content_memory
[index
+ 1] = val
;
2051 if (val
!= NOT_KNOWN
)
2053 content_memory
[val
] = index
+ 1;
2058 /* Any other places that had INDEX recorded as their contents are now invalid. */
2059 for (i
= 0; i
< sizeof content_memory
; i
++)
2062 || (val
!= NOT_KNOWN
&& i
== val
))
2069 if (content_memory
[i
] == index
2070 || (val
!= NOT_KNOWN
&& content_memory
[i
] == val
))
2072 content_memory
[i
] = NOT_KNOWN
;
2075 fprintf (dump_file
, " %s cleared\n", get_content_name (i
, mode
));
2078 content_memory
[++ i
] = NOT_KNOWN
;
2083 /* Record that LOC contains VALUE.
2084 For HImode locations record that LOC+1 contains VALUE+1.
2085 If LOC is not a register or stack slot, do nothing.
2086 If VALUE is not a register or stack slot, clear the recorded content. */
2089 record_content (rtx loc
, rtx value
)
2092 unsigned char index
;
2095 if ((index
= get_content_index (loc
)) == NOT_KNOWN
)
2098 val
= get_content_index (value
);
2100 mode
= GET_MODE (loc
);
2107 /* This should not happen when optimizing. */
2109 fprintf (stderr
, "ASSIGNMENT of location to itself detected! [%s]\n",
2110 get_content_name (val
, mode
));
2117 update_content (index
, val
, mode
);
2120 /* Returns TRUE if LOC already contains a copy of VALUE. */
2123 already_contains (rtx loc
, rtx value
)
2125 unsigned char index
;
2128 if ((index
= get_content_index (loc
)) == NOT_KNOWN
)
2131 if ((val
= get_content_index (value
)) == NOT_KNOWN
)
2134 if (content_memory
[index
] != val
)
2137 if (GET_MODE (loc
) == HImode
)
2138 return content_memory
[index
+ 1] == val
+ 1;
2144 rl78_es_addr (rtx addr
)
2146 if (GET_CODE (addr
) == MEM
)
2147 addr
= XEXP (addr
, 0);
2148 if (GET_CODE (addr
) != UNSPEC
)
2150 if (XINT (addr
, 1) != UNS_ES_ADDR
)
2156 rl78_es_base (rtx addr
)
2158 if (GET_CODE (addr
) == MEM
)
2159 addr
= XEXP (addr
, 0);
2160 addr
= XVECEXP (addr
, 0, 1);
2161 if (GET_CODE (addr
) == CONST
2162 && GET_CODE (XEXP (addr
, 0)) == ZERO_EXTRACT
)
2163 addr
= XEXP (XEXP (addr
, 0), 0);
2164 /* Mode doesn't matter here. */
2165 return gen_rtx_MEM (HImode
, addr
);
2168 /* Rescans an insn to see if it's recognized again. This is done
2169 carefully to ensure that all the constraint information is accurate
2170 for the newly matched insn. */
2172 insn_ok_now (rtx_insn
*insn
)
2174 rtx pattern
= PATTERN (insn
);
2177 INSN_CODE (insn
) = -1;
2179 if (recog (pattern
, insn
, 0) > -1)
2181 extract_insn (insn
);
2182 if (constrain_operands (1, get_preferred_alternatives (insn
)))
2185 fprintf (stderr
, "\033[32m");
2187 fprintf (stderr
, "\033[0m");
2189 if (SET_P (pattern
))
2190 record_content (SET_DEST (pattern
), SET_SRC (pattern
));
2192 /* We need to detect far addresses that haven't been
2193 converted to es/lo16 format. */
2194 for (i
=0; i
<recog_data
.n_operands
; i
++)
2195 if (GET_CODE (OP (i
)) == MEM
2196 && GET_MODE (XEXP (OP (i
), 0)) == SImode
2197 && GET_CODE (XEXP (OP (i
), 0)) != UNSPEC
)
2205 /* We need to re-recog the insn with virtual registers to get
2207 cfun
->machine
->virt_insns_ok
= 1;
2208 if (recog (pattern
, insn
, 0) > -1)
2210 extract_insn (insn
);
2211 if (constrain_operands (0, get_preferred_alternatives (insn
)))
2213 cfun
->machine
->virt_insns_ok
= 0;
2219 fprintf (stderr
, "\033[41;30m Unrecognized *virtual* insn \033[0m\n");
2226 fprintf (stderr
, "\033[31m");
2228 fprintf (stderr
, "\033[0m");
2234 #define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__)
2235 #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__)
2236 #define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable()
2237 #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; }
2238 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } FAILED
2240 #define FAILED gcc_unreachable ()
2241 #define MAYBE_OK(insn) if (insn_ok_now (insn)) return;
2242 #define MUST_BE_OK(insn) if (insn_ok_now (insn)) return; FAILED
2245 /* Registers into which we move the contents of virtual registers. */
2246 #define X gen_rtx_REG (QImode, X_REG)
2247 #define A gen_rtx_REG (QImode, A_REG)
2248 #define C gen_rtx_REG (QImode, C_REG)
2249 #define B gen_rtx_REG (QImode, B_REG)
2250 #define E gen_rtx_REG (QImode, E_REG)
2251 #define D gen_rtx_REG (QImode, D_REG)
2252 #define L gen_rtx_REG (QImode, L_REG)
2253 #define H gen_rtx_REG (QImode, H_REG)
2255 #define AX gen_rtx_REG (HImode, AX_REG)
2256 #define BC gen_rtx_REG (HImode, BC_REG)
2257 #define DE gen_rtx_REG (HImode, DE_REG)
2258 #define HL gen_rtx_REG (HImode, HL_REG)
2260 /* Returns TRUE if R is a virtual register. */
2262 is_virtual_register (rtx r
)
2264 return (GET_CODE (r
) == REG
2269 /* In all these alloc routines, we expect the following: the insn
2270 pattern is unshared, the insn was previously recognized and failed
2271 due to predicates or constraints, and the operand data is in
2274 static int virt_insn_was_frame
;
2276 /* Hook for all insns we emit. Re-mark them as FRAME_RELATED if
2279 EM2 (int line ATTRIBUTE_UNUSED
, rtx r
)
2282 fprintf (stderr
, "\033[36m%d: ", line
);
2284 fprintf (stderr
, "\033[0m");
2286 /*SCHED_GROUP_P (r) = 1;*/
2287 if (virt_insn_was_frame
)
2288 RTX_FRAME_RELATED_P (r
) = 1;
2292 #define EM(x) EM2 (__LINE__, x)
2294 /* Return a suitable RTX for the low half of a __far address. */
2296 rl78_lo16 (rtx addr
)
2300 if (GET_CODE (addr
) == SYMBOL_REF
2301 || GET_CODE (addr
) == CONST
)
2303 r
= gen_rtx_ZERO_EXTRACT (HImode
, addr
, GEN_INT (16), GEN_INT (0));
2304 r
= gen_rtx_CONST (HImode
, r
);
2307 r
= rl78_subreg (HImode
, addr
, SImode
, 0);
2309 r
= gen_es_addr (r
);
2314 /* Return a suitable RTX for the high half's lower byte of a __far address. */
2318 if (GET_CODE (addr
) == SYMBOL_REF
2319 || GET_CODE (addr
) == CONST
)
2321 rtx r
= gen_rtx_ZERO_EXTRACT (QImode
, addr
, GEN_INT (8), GEN_INT (16));
2322 r
= gen_rtx_CONST (QImode
, r
);
2325 return rl78_subreg (QImode
, addr
, SImode
, 2);
2329 add_postponed_content_update (rtx to
, rtx value
)
2331 unsigned char index
;
2333 if ((index
= get_content_index (to
)) == NOT_KNOWN
)
2336 gcc_assert (saved_update_index
== NOT_KNOWN
);
2337 saved_update_index
= index
;
2338 saved_update_value
= get_content_index (value
);
2339 saved_update_mode
= GET_MODE (to
);
2343 process_postponed_content_update (void)
2345 if (saved_update_index
!= NOT_KNOWN
)
2347 update_content (saved_update_index
, saved_update_value
, saved_update_mode
);
2348 saved_update_index
= NOT_KNOWN
;
2352 /* Generate and emit a move of (register) FROM into TO. if WHERE is not NULL
2353 then if BEFORE is true then emit the insn before WHERE, otherwise emit it
2354 after WHERE. If TO already contains FROM then do nothing. Returns TO if
2355 BEFORE is true, FROM otherwise. */
2357 gen_and_emit_move (rtx to
, rtx from
, rtx where
, bool before
)
2359 machine_mode mode
= GET_MODE (to
);
2361 if (optimize
&& before
&& already_contains (to
, from
))
2364 display_content_memory (stderr
);
2368 fprintf (dump_file
, " Omit move of %s into ",
2369 get_content_name (get_content_index (from
), mode
));
2370 fprintf (dump_file
, "%s as it already contains this value\n",
2371 get_content_name (get_content_index (to
), mode
));
2376 rtx move
= mode
== QImode
? gen_movqi (to
, from
) : gen_movhi (to
, from
);
2380 if (where
== NULL_RTX
)
2383 emit_insn_before (move
, where
);
2386 rtx note
= find_reg_note (where
, REG_EH_REGION
, NULL_RTX
);
2388 /* If necessary move REG_EH_REGION notes forward.
2389 cf. compiling gcc.dg/pr44545.c. */
2390 if (note
!= NULL_RTX
)
2392 add_reg_note (move
, REG_EH_REGION
, XEXP (note
, 0));
2393 remove_note (where
, note
);
2396 emit_insn_after (move
, where
);
2400 record_content (to
, from
);
2402 add_postponed_content_update (to
, from
);
2405 return before
? to
: from
;
2408 /* If M is MEM(REG) or MEM(PLUS(REG,INT)) and REG is virtual then
2409 copy it into NEWBASE and return the updated MEM. Otherwise just
2410 return M. Any needed insns are emitted before BEFORE. */
2412 transcode_memory_rtx (rtx m
, rtx newbase
, rtx before
)
2414 rtx base
, index
, addendr
;
2421 if (GET_MODE (XEXP (m
, 0)) == SImode
)
2424 rtx seg
= rl78_hi8 (XEXP (m
, 0));
2427 fprintf (stderr
, "setting ES:\n");
2430 emit_insn_before (EM (gen_movqi (A
, seg
)), before
);
2431 emit_insn_before (EM (gen_movqi_es (A
)), before
);
2432 record_content (A
, NULL_RTX
);
2434 new_m
= gen_rtx_MEM (GET_MODE (m
), rl78_lo16 (XEXP (m
, 0)));
2435 MEM_COPY_ATTRIBUTES (new_m
, m
);
2440 characterize_address (XEXP (m
, 0), & base
, & index
, & addendr
);
2441 gcc_assert (index
== NULL_RTX
);
2444 fprintf (stderr
, "\033[33m"); debug_rtx (m
); fprintf (stderr
, "\033[0m");
2447 if (base
== NULL_RTX
)
2450 if (addendr
&& GET_CODE (addendr
) == CONST_INT
)
2451 addend
= INTVAL (addendr
);
2453 gcc_assert (REG_P (base
));
2454 gcc_assert (REG_P (newbase
));
2456 if (REGNO (base
) == SP_REG
)
2458 if (addend
>= 0 && addend
<= 255)
2462 /* BASE should be a virtual register. We copy it to NEWBASE. If
2463 the addend is out of range for DE/HL, we use AX to compute the full
2467 || (addend
> 255 && REGNO (newbase
) != 2)
2468 || (addendr
&& GET_CODE (addendr
) != CONST_INT
))
2473 EM (emit_insn_before (gen_movhi (AX
, base
), before
));
2474 EM (emit_insn_before (gen_addhi3 (AX
, AX
, addendr
), before
));
2475 EM (emit_insn_before (gen_movhi (newbase
, AX
), before
));
2476 record_content (AX
, NULL_RTX
);
2477 record_content (newbase
, NULL_RTX
);
2484 base
= gen_and_emit_move (newbase
, base
, before
, true);
2489 record_content (base
, NULL_RTX
);
2490 base
= gen_rtx_PLUS (HImode
, base
, GEN_INT (addend
));
2494 fprintf (stderr
, "\033[33m");
2498 m
= change_address (m
, GET_MODE (m
), gen_es_addr (base
));
2500 m
= change_address (m
, GET_MODE (m
), base
);
2503 fprintf (stderr
, "\033[0m");
2508 /* Copy SRC to accumulator (A or AX), placing any generated insns
2509 before BEFORE. Returns accumulator RTX. */
2511 move_to_acc (int opno
, rtx before
)
2513 rtx src
= OP (opno
);
2514 machine_mode mode
= GET_MODE (src
);
2516 if (REG_P (src
) && REGNO (src
) < 2)
2519 if (mode
== VOIDmode
)
2520 mode
= recog_data
.operand_mode
[opno
];
2522 return gen_and_emit_move (mode
== QImode
? A
: AX
, src
, before
, true);
2526 force_into_acc (rtx src
, rtx before
)
2528 machine_mode mode
= GET_MODE (src
);
2531 if (REG_P (src
) && REGNO (src
) < 2)
2534 move
= mode
== QImode
? gen_movqi (A
, src
) : gen_movhi (AX
, src
);
2538 emit_insn_before (move
, before
);
2539 record_content (AX
, NULL_RTX
);
2542 /* Copy accumulator (A or AX) to DEST, placing any generated insns
2543 after AFTER. Returns accumulator RTX. */
2545 move_from_acc (unsigned int opno
, rtx after
)
2547 rtx dest
= OP (opno
);
2548 machine_mode mode
= GET_MODE (dest
);
2550 if (REG_P (dest
) && REGNO (dest
) < 2)
2553 return gen_and_emit_move (dest
, mode
== QImode
? A
: AX
, after
, false);
2556 /* Copy accumulator (A or AX) to REGNO, placing any generated insns
2557 before BEFORE. Returns reg RTX. */
2559 move_acc_to_reg (rtx acc
, int regno
, rtx before
)
2561 machine_mode mode
= GET_MODE (acc
);
2564 reg
= gen_rtx_REG (mode
, regno
);
2566 return gen_and_emit_move (reg
, acc
, before
, true);
2569 /* Copy SRC to X, placing any generated insns before BEFORE.
2572 move_to_x (int opno
, rtx before
)
2574 rtx src
= OP (opno
);
2575 machine_mode mode
= GET_MODE (src
);
2578 if (mode
== VOIDmode
)
2579 mode
= recog_data
.operand_mode
[opno
];
2580 reg
= (mode
== QImode
) ? X
: AX
;
2582 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
2584 OP (opno
) = move_to_acc (opno
, before
);
2585 OP (opno
) = move_acc_to_reg (OP (opno
), X_REG
, before
);
2589 return gen_and_emit_move (reg
, src
, before
, true);
2592 /* Copy OP (opno) to H or HL, placing any generated insns before BEFORE.
2593 Returns H/HL RTX. */
2595 move_to_hl (int opno
, rtx before
)
2597 rtx src
= OP (opno
);
2598 machine_mode mode
= GET_MODE (src
);
2601 if (mode
== VOIDmode
)
2602 mode
= recog_data
.operand_mode
[opno
];
2603 reg
= (mode
== QImode
) ? L
: HL
;
2605 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
2607 OP (opno
) = move_to_acc (opno
, before
);
2608 OP (opno
) = move_acc_to_reg (OP (opno
), L_REG
, before
);
2612 return gen_and_emit_move (reg
, src
, before
, true);
2615 /* Copy OP (opno) to E or DE, placing any generated insns before BEFORE.
2616 Returns E/DE RTX. */
2618 move_to_de (int opno
, rtx before
)
2620 rtx src
= OP (opno
);
2621 machine_mode mode
= GET_MODE (src
);
2624 if (mode
== VOIDmode
)
2625 mode
= recog_data
.operand_mode
[opno
];
2627 reg
= (mode
== QImode
) ? E
: DE
;
2629 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
2631 OP (opno
) = move_to_acc (opno
, before
);
2632 OP (opno
) = move_acc_to_reg (OP (opno
), E_REG
, before
);
2636 gen_and_emit_move (reg
, src
, before
, true);
2642 /* Devirtualize an insn of the form (SET (op) (unop (op))). */
2644 rl78_alloc_physical_registers_op1 (rtx_insn
*insn
)
2646 /* op[0] = func op[1] */
2648 /* We first try using A as the destination, then copying it
2650 if (rtx_equal_p (OP (0), OP (1)))
2653 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2657 /* If necessary, load the operands into BC and HL.
2658 Check to see if we already have OP (0) in HL
2659 and if so, swap the order. */
2661 && already_contains (HL
, XEXP (OP (0), 0)))
2663 OP (0) = transcode_memory_rtx (OP (0), HL
, insn
);
2664 OP (1) = transcode_memory_rtx (OP (1), BC
, insn
);
2668 OP (0) = transcode_memory_rtx (OP (0), BC
, insn
);
2669 OP (1) = transcode_memory_rtx (OP (1), HL
, insn
);
2675 OP (0) = move_from_acc (0, insn
);
2679 /* Try copying the src to acc first, then. This is for, for
2680 example, ZERO_EXTEND or NOT. */
2681 OP (1) = move_to_acc (1, insn
);
2686 /* Returns true if operand OPNUM contains a constraint of type CONSTRAINT.
2687 Assumes that the current insn has already been recognised and hence the
2688 constraint data has been filled in. */
2690 has_constraint (unsigned int opnum
, enum constraint_num constraint
)
2692 const char * p
= recog_data
.constraints
[opnum
];
2694 /* No constraints means anything is accepted. */
2695 if (p
== NULL
|| *p
== 0 || *p
== ',')
2704 len
= CONSTRAINT_LEN (c
, p
);
2705 gcc_assert (len
> 0);
2713 if (lookup_constraint (p
) == constraint
)
2721 /* Devirtualize an insn of the form (SET (op) (binop (op) (op))). */
2723 rl78_alloc_physical_registers_op2 (rtx_insn
*insn
)
2731 if (rtx_equal_p (OP (0), OP (1)))
2734 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2735 OP (2) = transcode_memory_rtx (OP (2), HL
, insn
);
2737 else if (rtx_equal_p (OP (0), OP (2)))
2739 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2741 OP (2) = transcode_memory_rtx (OP (2), HL
, insn
);
2745 OP (0) = transcode_memory_rtx (OP (0), BC
, insn
);
2746 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2747 OP (2) = transcode_memory_rtx (OP (2), HL
, insn
);
2752 prev
= prev_nonnote_nondebug_insn (insn
);
2753 if (recog_data
.constraints
[1][0] == '%'
2754 && is_virtual_register (OP (1))
2755 && ! is_virtual_register (OP (2))
2756 && ! CONSTANT_P (OP (2)))
2763 /* Make a note of whether (H)L is being used. It matters
2764 because if OP (2) also needs reloading, then we must take
2765 care not to corrupt HL. */
2766 hl_used
= reg_mentioned_p (L
, OP (0)) || reg_mentioned_p (L
, OP (1));
2768 /* If HL is not currently being used and dest == op1 then there are
2769 some possible optimizations available by reloading one of the
2770 operands into HL, before trying to use the accumulator. */
2773 && rtx_equal_p (OP (0), OP (1)))
2775 /* If op0 is a Ws1 type memory address then switching the base
2776 address register to HL might allow us to perform an in-memory
2777 operation. (eg for the INCW instruction).
2779 FIXME: Adding the move into HL is costly if this optimization is not
2780 going to work, so for now, make sure that we know that the new insn will
2781 match the requirements of the addhi3_real pattern. Really we ought to
2782 generate a candidate sequence, test that, and then install it if the
2783 results are good. */
2784 if (satisfies_constraint_Ws1 (OP (0))
2785 && has_constraint (0, CONSTRAINT_Wh1
)
2786 && (satisfies_constraint_K (OP (2)) || satisfies_constraint_L (OP (2))))
2788 rtx base
, index
, addend
, newbase
;
2790 characterize_address (XEXP (OP (0), 0), & base
, & index
, & addend
);
2791 gcc_assert (index
== NULL_RTX
);
2792 gcc_assert (REG_P (base
) && REGNO (base
) == SP_REG
);
2794 /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */
2795 if (addend
!= NULL_RTX
)
2797 newbase
= gen_and_emit_move (HL
, base
, insn
, true);
2798 record_content (newbase
, NULL_RTX
);
2799 newbase
= gen_rtx_PLUS (HImode
, newbase
, addend
);
2801 OP (0) = OP (1) = change_address (OP (0), VOIDmode
, newbase
);
2803 /* We do not want to fail here as this means that
2804 we have inserted useless insns into the stream. */
2808 else if (REG_P (OP (0))
2809 && satisfies_constraint_Ws1 (OP (2))
2810 && has_constraint (2, CONSTRAINT_Wh1
))
2812 rtx base
, index
, addend
, newbase
;
2814 characterize_address (XEXP (OP (2), 0), & base
, & index
, & addend
);
2815 gcc_assert (index
== NULL_RTX
);
2816 gcc_assert (REG_P (base
) && REGNO (base
) == SP_REG
);
2818 /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */
2819 if (addend
!= NULL_RTX
)
2821 gen_and_emit_move (HL
, base
, insn
, true);
2823 if (REGNO (OP (0)) != X_REG
)
2825 OP (1) = move_to_acc (1, insn
);
2826 OP (0) = move_from_acc (0, insn
);
2829 record_content (HL
, NULL_RTX
);
2830 newbase
= gen_rtx_PLUS (HImode
, HL
, addend
);
2832 OP (2) = change_address (OP (2), VOIDmode
, newbase
);
2834 /* We do not want to fail here as this means that
2835 we have inserted useless insns into the stream. */
2841 OP (0) = move_from_acc (0, insn
);
2843 tmp_id
= get_max_insn_count ();
2846 if (rtx_equal_p (OP (1), OP (2)))
2847 OP (2) = OP (1) = move_to_acc (1, insn
);
2849 OP (1) = move_to_acc (1, insn
);
2853 /* If we omitted the move of OP1 into the accumulator (because
2854 it was already there from a previous insn), then force the
2855 generation of the move instruction now. We know that we
2856 are about to emit a move into HL (or DE) via AX, and hence
2857 our optimization to remove the load of OP1 is no longer valid. */
2858 if (tmp_id
== get_max_insn_count ())
2859 force_into_acc (saved_op1
, insn
);
2861 /* We have to copy op2 to HL (or DE), but that involves AX, which
2862 already has a live value. Emit it before those insns. */
2865 first
= next_nonnote_nondebug_insn (prev
);
2867 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
2870 OP (2) = hl_used
? move_to_de (2, first
) : move_to_hl (2, first
);
2875 /* Devirtualize an insn of the form SET (PC) (MEM/REG). */
2877 rl78_alloc_physical_registers_ro1 (rtx_insn
*insn
)
2879 OP (0) = transcode_memory_rtx (OP (0), BC
, insn
);
2883 OP (0) = move_to_acc (0, insn
);
2888 /* Devirtualize a compare insn. */
2890 rl78_alloc_physical_registers_cmp (rtx_insn
*insn
)
2894 rtx prev
= prev_nonnote_nondebug_insn (insn
);
2897 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2898 OP (2) = transcode_memory_rtx (OP (2), HL
, insn
);
2900 /* HI compares have to have OP (1) in AX, but QI
2901 compares do not, so it is worth checking here. */
2904 /* For an HImode compare, OP (1) must always be in AX.
2905 But if OP (1) is a REG (and not AX), then we can avoid
2906 a reload of OP (1) if we reload OP (2) into AX and invert
2909 && REGNO (OP (1)) != AX_REG
2910 && GET_MODE (OP (1)) == HImode
2913 rtx cmp
= XEXP (SET_SRC (PATTERN (insn
)), 0);
2915 OP (2) = move_to_acc (2, insn
);
2917 switch (GET_CODE (cmp
))
2922 case LTU
: cmp
= gen_rtx_GTU (HImode
, OP (2), OP (1)); break;
2923 case GTU
: cmp
= gen_rtx_LTU (HImode
, OP (2), OP (1)); break;
2924 case LEU
: cmp
= gen_rtx_GEU (HImode
, OP (2), OP (1)); break;
2925 case GEU
: cmp
= gen_rtx_LEU (HImode
, OP (2), OP (1)); break;
2938 if (GET_CODE (cmp
) == EQ
|| GET_CODE (cmp
) == NE
)
2939 PATTERN (insn
) = gen_cbranchhi4_real (cmp
, OP (2), OP (1), OP (3));
2941 PATTERN (insn
) = gen_cbranchhi4_real_inverted (cmp
, OP (2), OP (1), OP (3));
2946 /* Surprisingly, gcc can generate a comparison of a register with itself, but this
2947 should be handled by the second alternative of the cbranchhi_real pattern. */
2948 if (rtx_equal_p (OP (1), OP (2)))
2950 OP (1) = OP (2) = BC
;
2954 tmp_id
= get_max_insn_count ();
2957 OP (1) = move_to_acc (1, insn
);
2961 /* If we omitted the move of OP1 into the accumulator (because
2962 it was already there from a previous insn), then force the
2963 generation of the move instruction now. We know that we
2964 are about to emit a move into HL via AX, and hence our
2965 optimization to remove the load of OP1 is no longer valid. */
2966 if (tmp_id
== get_max_insn_count ())
2967 force_into_acc (saved_op1
, insn
);
2969 /* We have to copy op2 to HL, but that involves the acc, which
2970 already has a live value. Emit it before those insns. */
2972 first
= next_nonnote_nondebug_insn (prev
);
2974 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
2976 OP (2) = move_to_hl (2, first
);
2981 /* Like op2, but AX = A * X. */
2983 rl78_alloc_physical_registers_umul (rtx_insn
*insn
)
2985 rtx prev
= prev_nonnote_nondebug_insn (insn
);
2990 OP (0) = transcode_memory_rtx (OP (0), BC
, insn
);
2991 OP (1) = transcode_memory_rtx (OP (1), DE
, insn
);
2992 OP (2) = transcode_memory_rtx (OP (2), HL
, insn
);
2996 if (recog_data
.constraints
[1][0] == '%'
2997 && is_virtual_register (OP (1))
2998 && !is_virtual_register (OP (2))
2999 && !CONSTANT_P (OP (2)))
3006 OP (0) = move_from_acc (0, insn
);
3008 tmp_id
= get_max_insn_count ();
3011 if (rtx_equal_p (OP (1), OP (2)))
3013 gcc_assert (GET_MODE (OP (2)) == QImode
);
3014 /* The MULU instruction does not support duplicate arguments
3015 but we know that if we copy OP (2) to X it will do so via
3016 A and thus OP (1) will already be loaded into A. */
3017 OP (2) = move_to_x (2, insn
);
3021 OP (1) = move_to_acc (1, insn
);
3025 /* If we omitted the move of OP1 into the accumulator (because
3026 it was already there from a previous insn), then force the
3027 generation of the move instruction now. We know that we
3028 are about to emit a move into HL (or DE) via AX, and hence
3029 our optimization to remove the load of OP1 is no longer valid. */
3030 if (tmp_id
== get_max_insn_count ())
3031 force_into_acc (saved_op1
, insn
);
3033 /* We have to copy op2 to X, but that involves the acc, which
3034 already has a live value. Emit it before those insns. */
3037 first
= next_nonnote_nondebug_insn (prev
);
3039 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
3041 OP (2) = move_to_x (2, first
);
3047 rl78_alloc_address_registers_macax (rtx_insn
*insn
)
3050 bool replace_in_op0
= false;
3051 bool replace_in_op1
= false;
3055 /* Two different MEMs are not allowed. */
3057 for (op
= 2; op
>= 0; op
--)
3059 if (MEM_P (OP (op
)))
3061 if (op
== 0 && replace_in_op0
)
3063 if (op
== 1 && replace_in_op1
)
3069 /* If we replace a MEM, make sure that we replace it for all
3070 occurrences of the same MEM in the insn. */
3071 replace_in_op0
= (op
> 0 && rtx_equal_p (OP (op
), OP (0)));
3072 replace_in_op1
= (op
> 1 && rtx_equal_p (OP (op
), OP (1)));
3074 OP (op
) = transcode_memory_rtx (OP (op
), HL
, insn
);
3077 && ((GET_CODE (XEXP (OP (op
), 0)) == REG
3078 && REGNO (XEXP (OP (op
), 0)) == SP_REG
)
3079 || (GET_CODE (XEXP (OP (op
), 0)) == PLUS
3080 && REGNO (XEXP (XEXP (OP (op
), 0), 0)) == SP_REG
)))
3082 emit_insn_before (gen_movhi (HL
, gen_rtx_REG (HImode
, SP_REG
)), insn
);
3083 OP (op
) = replace_rtx (OP (op
), gen_rtx_REG (HImode
, SP_REG
), HL
);
3091 OP (op
) = transcode_memory_rtx (OP (op
), DE
, insn
);
3094 OP (op
) = transcode_memory_rtx (OP (op
), BC
, insn
);
3104 /* Scan all insns and devirtualize them. */
3106 rl78_alloc_physical_registers (void)
3108 /* During most of the compile, gcc is dealing with virtual
3109 registers. At this point, we need to assign physical registers
3110 to the vitual ones, and copy in/out as needed. */
3112 rtx_insn
*insn
, *curr
;
3113 enum attr_valloc valloc_method
;
3115 for (insn
= get_insns (); insn
; insn
= curr
)
3119 curr
= next_nonnote_nondebug_insn (insn
);
3122 && (GET_CODE (PATTERN (insn
)) == SET
3123 || GET_CODE (PATTERN (insn
)) == CALL
)
3124 && INSN_CODE (insn
) == -1)
3126 if (GET_CODE (SET_SRC (PATTERN (insn
))) == ASM_OPERANDS
)
3128 i
= recog (PATTERN (insn
), insn
, 0);
3134 INSN_CODE (insn
) = i
;
3138 cfun
->machine
->virt_insns_ok
= 0;
3139 cfun
->machine
->real_insns_ok
= 1;
3141 clear_content_memory ();
3143 for (insn
= get_insns (); insn
; insn
= curr
)
3147 curr
= insn
? next_nonnote_nondebug_insn (insn
) : NULL
;
3152 clear_content_memory ();
3158 fprintf (dump_file
, "Converting insn %d\n", INSN_UID (insn
));
3160 pattern
= PATTERN (insn
);
3161 if (GET_CODE (pattern
) == PARALLEL
)
3162 pattern
= XVECEXP (pattern
, 0, 0);
3163 if (JUMP_P (insn
) || CALL_P (insn
) || GET_CODE (pattern
) == CALL
)
3164 clear_content_memory ();
3165 if (GET_CODE (pattern
) != SET
3166 && GET_CODE (pattern
) != CALL
)
3168 if (GET_CODE (pattern
) == SET
3169 && GET_CODE (SET_SRC (pattern
)) == ASM_OPERANDS
)
3172 valloc_method
= get_attr_valloc (insn
);
3174 PATTERN (insn
) = copy_rtx_if_shared (PATTERN (insn
));
3176 if (valloc_method
== VALLOC_MACAX
)
3178 record_content (AX
, NULL_RTX
);
3179 record_content (BC
, NULL_RTX
);
3180 record_content (DE
, NULL_RTX
);
3183 if (insn_ok_now (insn
))
3186 INSN_CODE (insn
) = -1;
3188 if (RTX_FRAME_RELATED_P (insn
))
3189 virt_insn_was_frame
= 1;
3191 virt_insn_was_frame
= 0;
3193 switch (valloc_method
)
3196 rl78_alloc_physical_registers_op1 (insn
);
3199 rl78_alloc_physical_registers_op2 (insn
);
3202 rl78_alloc_physical_registers_ro1 (insn
);
3205 rl78_alloc_physical_registers_cmp (insn
);
3208 rl78_alloc_physical_registers_umul (insn
);
3211 /* Macro that clobbers AX. */
3212 rl78_alloc_address_registers_macax (insn
);
3213 record_content (AX
, NULL_RTX
);
3214 record_content (BC
, NULL_RTX
);
3215 record_content (DE
, NULL_RTX
);
3219 if (JUMP_P (insn
) || CALL_P (insn
) || GET_CODE (pattern
) == CALL
)
3220 clear_content_memory ();
3222 process_postponed_content_update ();
3226 fprintf (stderr
, "\033[0m");
3230 /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN.
3231 This function scans for uses of registers; the last use (i.e. first
3232 encounter when scanning backwards) triggers a REG_DEAD note if the
3233 reg was previously in DEAD[]. */
3235 rl78_note_reg_uses (char *dead
, rtx s
, rtx insn
)
3244 code
= GET_CODE (s
);
3248 /* Compare registers by number. */
3253 fprintf (dump_file
, "note use reg %d size %d on insn %d\n",
3254 r
, GET_MODE_SIZE (GET_MODE (s
)), INSN_UID (insn
));
3255 print_rtl_single (dump_file
, s
);
3258 add_reg_note (insn
, REG_DEAD
, gen_rtx_REG (GET_MODE (s
), r
));
3259 for (i
= 0; i
< GET_MODE_SIZE (GET_MODE (s
)); i
++)
3263 /* These codes have no constituent expressions
3274 /* These are kept unique for a given value. */
3281 fmt
= GET_RTX_FORMAT (code
);
3283 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3288 for (j
= XVECLEN (s
, i
) - 1; j
>= 0; j
--)
3289 rl78_note_reg_uses (dead
, XVECEXP (s
, i
, j
), insn
);
3291 else if (fmt
[i
] == 'e')
3292 rl78_note_reg_uses (dead
, XEXP (s
, i
), insn
);
3296 /* Like the previous function, but scan for SETs instead. */
3298 rl78_note_reg_set (char *dead
, rtx d
, rtx insn
)
3302 if (GET_CODE (d
) != REG
)
3307 add_reg_note (insn
, REG_UNUSED
, gen_rtx_REG (GET_MODE (d
), r
));
3309 fprintf (dump_file
, "note set reg %d size %d\n", r
, GET_MODE_SIZE (GET_MODE (d
)));
3310 for (i
= 0; i
< GET_MODE_SIZE (GET_MODE (d
)); i
++)
3314 /* This is a rather crude register death pass. Death status is reset
3315 at every jump or call insn. */
3317 rl78_calculate_death_notes (void)
3319 char dead
[FIRST_PSEUDO_REGISTER
];
3323 memset (dead
, 0, sizeof (dead
));
3325 for (insn
= get_last_insn ();
3327 insn
= prev_nonnote_nondebug_insn (insn
))
3331 fprintf (dump_file
, "\n--------------------------------------------------");
3332 fprintf (dump_file
, "\nDead:");
3333 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3335 fprintf (dump_file
, " %s", reg_names
[i
]);
3336 fprintf (dump_file
, "\n");
3337 print_rtl_single (dump_file
, insn
);
3340 switch (GET_CODE (insn
))
3344 switch (GET_CODE (p
))
3349 rl78_note_reg_set (dead
, d
, insn
);
3350 rl78_note_reg_uses (dead
, s
, insn
);
3354 rl78_note_reg_uses (dead
, p
, insn
);
3363 if (INSN_CODE (insn
) == CODE_FOR_rl78_return
)
3365 memset (dead
, 1, sizeof (dead
));
3366 /* We expect a USE just prior to this, which will mark
3367 the actual return registers. The USE will have a
3368 death note, but we aren't going to be modifying it
3373 memset (dead
, 0, sizeof (dead
));
3380 print_rtl_single (dump_file
, insn
);
3384 /* Helper function to reset the origins in RP and the age in AGE for
3387 reset_origins (int *rp
, int *age
)
3390 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3397 /* The idea behind this optimization is to look for cases where we
3398 move data from A to B to C, and instead move from A to B, and A to
3399 C. If B is a virtual register or memory, this is a big win on its
3400 own. If B turns out to be unneeded after this, it's a bigger win.
3401 For each register, we try to determine where it's value originally
3402 came from, if it's propogated purely through moves (and not
3403 computes). The ORIGINS[] array has the regno for the "origin" of
3404 the value in the [regno] it's indexed by. */
3406 rl78_propogate_register_origins (void)
3408 int origins
[FIRST_PSEUDO_REGISTER
];
3409 int age
[FIRST_PSEUDO_REGISTER
];
3411 rtx_insn
*insn
, *ninsn
= NULL
;
3414 reset_origins (origins
, age
);
3416 for (insn
= get_insns (); insn
; insn
= ninsn
)
3418 ninsn
= next_nonnote_nondebug_insn (insn
);
3422 fprintf (dump_file
, "\n");
3423 fprintf (dump_file
, "Origins:");
3424 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3425 if (origins
[i
] != i
)
3426 fprintf (dump_file
, " r%d=r%d", i
, origins
[i
]);
3427 fprintf (dump_file
, "\n");
3428 print_rtl_single (dump_file
, insn
);
3431 switch (GET_CODE (insn
))
3437 reset_origins (origins
, age
);
3444 pat
= PATTERN (insn
);
3446 if (GET_CODE (pat
) == PARALLEL
)
3448 rtx clobber
= XVECEXP (pat
, 0, 1);
3449 pat
= XVECEXP (pat
, 0, 0);
3450 if (GET_CODE (clobber
) == CLOBBER
3451 && GET_CODE (XEXP (clobber
, 0)) == REG
)
3453 int cr
= REGNO (XEXP (clobber
, 0));
3454 int mb
= GET_MODE_SIZE (GET_MODE (XEXP (clobber
, 0)));
3456 fprintf (dump_file
, "reset origins of %d regs at %d\n", mb
, cr
);
3457 for (i
= 0; i
< mb
; i
++)
3459 origins
[cr
+ i
] = cr
+ i
;
3467 if (GET_CODE (pat
) == SET
)
3469 rtx src
= SET_SRC (pat
);
3470 rtx dest
= SET_DEST (pat
);
3471 int mb
= GET_MODE_SIZE (GET_MODE (dest
));
3473 if (GET_CODE (dest
) == REG
)
3475 int dr
= REGNO (dest
);
3477 if (GET_CODE (src
) == REG
)
3479 int sr
= REGNO (src
);
3481 int best_age
, best_reg
;
3483 /* See if the copy is not needed. */
3484 for (i
= 0; i
< mb
; i
++)
3485 if (origins
[dr
+ i
] != origins
[sr
+ i
])
3490 fprintf (dump_file
, "deleting because dest already has correct value\n");
3495 if (dr
< 8 || sr
>= 8)
3501 /* See if the copy can be made from another
3502 bank 0 register instead, instead of the
3503 virtual src register. */
3504 for (ar
= 0; ar
< 8; ar
+= mb
)
3507 for (i
= 0; i
< mb
; i
++)
3508 if (origins
[ar
+ i
] != origins
[sr
+ i
])
3511 /* The chip has some reg-reg move limitations. */
3512 if (mb
== 1 && dr
> 3)
3517 if (best_age
== -1 || best_age
> age
[sr
+ i
])
3519 best_age
= age
[sr
+ i
];
3527 /* FIXME: copy debug info too. */
3528 SET_SRC (pat
) = gen_rtx_REG (GET_MODE (src
), best_reg
);
3533 for (i
= 0; i
< mb
; i
++)
3535 origins
[dr
+ i
] = origins
[sr
+ i
];
3536 age
[dr
+ i
] = age
[sr
+ i
] + 1;
3541 /* The destination is computed, its origin is itself. */
3543 fprintf (dump_file
, "resetting origin of r%d for %d byte%s\n",
3544 dr
, mb
, mb
== 1 ? "" : "s");
3545 for (i
= 0; i
< mb
; i
++)
3547 origins
[dr
+ i
] = dr
+ i
;
3552 /* Any registers marked with that reg as an origin are reset. */
3553 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3554 if (origins
[i
] >= dr
&& origins
[i
] < dr
+ mb
)
3561 /* Special case - our ADDSI3 macro uses AX and sometimes BC. */
3562 if (get_attr_valloc (insn
) == VALLOC_MACAX
)
3565 fprintf (dump_file
, "Resetting origin of AX/BC for macro.\n");
3566 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3567 if (i
<= 3 || origins
[i
] <= 3)
3574 if (GET_CODE (src
) == ASHIFT
3575 || GET_CODE (src
) == ASHIFTRT
3576 || GET_CODE (src
) == LSHIFTRT
)
3578 rtx count
= XEXP (src
, 1);
3579 if (GET_CODE (count
) == REG
)
3581 /* Special case - our pattern clobbers the count register. */
3582 int r
= REGNO (count
);
3584 fprintf (dump_file
, "Resetting origin of r%d for shift.\n", r
);
3585 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3586 if (i
== r
|| origins
[i
] == r
)
3594 else if (GET_CODE (pat
) == CLOBBER
3595 && GET_CODE (XEXP (pat
, 0)) == REG
)
3597 if (REG_P (XEXP (pat
, 0)))
3599 unsigned int reg
= REGNO (XEXP (pat
, 0));
3609 /* Remove any SETs where the destination is unneeded. */
3611 rl78_remove_unused_sets (void)
3613 rtx_insn
*insn
, *ninsn
= NULL
;
3616 for (insn
= get_insns (); insn
; insn
= ninsn
)
3618 ninsn
= next_nonnote_nondebug_insn (insn
);
3620 rtx set
= single_set (insn
);
3624 dest
= SET_DEST (set
);
3626 if (GET_CODE (dest
) != REG
|| REGNO (dest
) > 23)
3629 if (find_regno_note (insn
, REG_UNUSED
, REGNO (dest
)))
3634 /* This is the top of the devritualization pass. */
3638 /* split2 only happens when optimizing, but we need all movSIs to be
3643 rl78_alloc_physical_registers ();
3647 fprintf (dump_file
, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n");
3648 print_rtl_with_bb (dump_file
, get_insns (), 0);
3651 rl78_propogate_register_origins ();
3652 rl78_calculate_death_notes ();
3656 fprintf (dump_file
, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n");
3657 print_rtl_with_bb (dump_file
, get_insns (), 0);
3658 fprintf (dump_file
, "\n======================================================================\n");
3661 rl78_remove_unused_sets ();
3663 /* The code after devirtualizing has changed so much that at this point
3664 we might as well just rescan everything. Note that
3665 df_rescan_all_insns is not going to help here because it does not
3666 touch the artificial uses and defs. */
3667 df_finish_pass (true);
3669 df_live_add_problem ();
3670 df_scan_alloc (NULL
);
3677 #undef TARGET_RETURN_IN_MEMORY
3678 #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory
3681 rl78_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3683 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
3684 return (size
== -1 || size
> 8);
3688 #undef TARGET_RTX_COSTS
3689 #define TARGET_RTX_COSTS rl78_rtx_costs
3691 static bool rl78_rtx_costs (rtx x
,
3693 int outer_code ATTRIBUTE_UNUSED
,
3694 int opno ATTRIBUTE_UNUSED
,
3696 bool speed ATTRIBUTE_UNUSED
)
3698 if (code
== IF_THEN_ELSE
)
3699 return COSTS_N_INSNS (10);
3700 if (GET_MODE (x
) == SImode
)
3706 *total
= COSTS_N_INSNS (14);
3707 else if (RL78_MUL_G13
)
3708 *total
= COSTS_N_INSNS (29);
3710 *total
= COSTS_N_INSNS (500);
3713 *total
= COSTS_N_INSNS (8);
3718 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3720 switch (INTVAL (XEXP (x
, 1)))
3722 case 0: *total
= COSTS_N_INSNS (0); break;
3723 case 1: *total
= COSTS_N_INSNS (6); break;
3724 case 2: case 3: case 4: case 5: case 6: case 7:
3725 *total
= COSTS_N_INSNS (10); break;
3726 case 8: *total
= COSTS_N_INSNS (6); break;
3727 case 9: case 10: case 11: case 12: case 13: case 14: case 15:
3728 *total
= COSTS_N_INSNS (10); break;
3729 case 16: *total
= COSTS_N_INSNS (3); break;
3730 case 17: case 18: case 19: case 20: case 21: case 22: case 23:
3731 *total
= COSTS_N_INSNS (4); break;
3732 case 24: *total
= COSTS_N_INSNS (4); break;
3733 case 25: case 26: case 27: case 28: case 29: case 30: case 31:
3734 *total
= COSTS_N_INSNS (5); break;
3738 *total
= COSTS_N_INSNS (10+4*16);
3746 #undef TARGET_UNWIND_WORD_MODE
3747 #define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode
3750 rl78_unwind_word_mode (void)
3756 struct gcc_target targetm
= TARGET_INITIALIZER
;
3758 #include "gt-rl78.h"