1 /* Subroutines used for code generation on Renesas RL78 processors.
2 Copyright (C) 2011, 2012 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"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
32 #include "insn-attr.h"
39 #include "diagnostic-core.h"
47 #include "target-def.h"
48 #include "langhooks.h"
49 #include "rl78-protos.h"
51 #include "tree-pass.h"
53 static inline bool is_interrupt_func (const_tree decl
);
54 static inline bool is_brk_interrupt_func (const_tree decl
);
55 static void rl78_reorg (void);
58 /* Debugging statements are tagged with DEBUG0 only so that they can
59 be easily enabled individually, by replacing the '0' with '1' as
64 /* REGISTER_NAMES has the names for individual 8-bit registers, but
65 these have the names we need to use when referring to 16-bit
67 static const char * const word_regnames
[] =
69 "ax", "AX", "bc", "BC", "de", "DE", "hl", "HL",
70 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
71 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
72 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
73 "sp", "ap", "psw", "es", "cs"
76 struct GTY(()) machine_function
78 /* If set, the rest of the fields have been computed. */
80 /* Which register pairs need to be pushed in the prologue. */
81 int need_to_push
[FIRST_PSEUDO_REGISTER
/ 2];
83 /* These fields describe the frame layout... */
85 /* 4 bytes for saved PC */
89 int framesize_outgoing
;
93 /* If set, recog is allowed to match against the "real" patterns. */
95 /* If set, recog is allowed to match against the "virtual" patterns. */
97 /* Set if the current function needs to clean up any trampolines. */
101 /* This is our init_machine_status, as set in
102 rl78_option_override. */
103 static struct machine_function
*
104 rl78_init_machine_status (void)
106 struct machine_function
*m
;
108 m
= ggc_alloc_cleared_machine_function ();
109 m
->virt_insns_ok
= 1;
114 /* Returns whether to run the devirtualization pass. */
121 /* Runs the devirtualization pass. */
129 /* This pass converts virtual instructions using virtual registers, to
130 real instructions using real registers. Rather than run it as
131 reorg, we reschedule it before vartrack to help with debugging. */
132 static struct opt_pass rl78_devirt_pass
=
136 OPTGROUP_NONE
, /* optinfo_flags */
148 static struct register_pass_info rl78_devirt_info
=
153 PASS_POS_INSERT_BEFORE
156 #undef TARGET_ASM_FILE_START
157 #define TARGET_ASM_FILE_START rl78_asm_file_start
160 rl78_asm_file_start (void)
164 for (i
= 0; i
< 8; i
++)
166 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", 8 + i
, 0xffef0 + i
);
167 fprintf (asm_out_file
, "r%d\t=\t0x%x\n", 16 + i
, 0xffee8 + i
);
170 register_pass (& rl78_devirt_info
);
174 #undef TARGET_OPTION_OVERRIDE
175 #define TARGET_OPTION_OVERRIDE rl78_option_override
178 rl78_option_override (void)
180 flag_omit_frame_pointer
= 1;
181 flag_no_function_cse
= 1;
182 flag_split_wide_types
= 0;
184 init_machine_status
= rl78_init_machine_status
;
187 /* Most registers are 8 bits. Some are 16 bits because, for example,
188 gcc doesn't like dealing with $FP as a register pair. This table
189 maps register numbers to size in bytes. */
190 static const int register_sizes
[] =
192 1, 1, 1, 1, 1, 1, 1, 1,
193 1, 1, 1, 1, 1, 1, 1, 1,
194 1, 1, 1, 1, 1, 1, 2, 1,
195 1, 1, 1, 1, 1, 1, 1, 1,
199 /* Predicates used in the MD patterns. This one is true when virtual
200 insns may be matched, which typically means before (or during) the
203 rl78_virt_insns_ok (void)
206 return cfun
->machine
->virt_insns_ok
;
210 /* Predicates used in the MD patterns. This one is true when real
211 insns may be matched, which typically means after (or during) the
214 rl78_real_insns_ok (void)
217 return cfun
->machine
->real_insns_ok
;
221 /* Implements HARD_REGNO_NREGS. */
223 rl78_hard_regno_nregs (int regno
, enum machine_mode mode
)
225 int rs
= register_sizes
[regno
];
228 return ((GET_MODE_SIZE (mode
) + rs
- 1) / rs
);
231 /* Implements HARD_REGNO_MODE_OK. */
233 rl78_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
235 int s
= GET_MODE_SIZE (mode
);
239 /* These are not to be used by gcc. */
240 if (regno
== 23 || regno
== ES_REG
|| regno
== CS_REG
)
242 /* $fp can alway sbe accessed as a 16-bit value. */
243 if (regno
== FP_REG
&& s
== 2)
247 /* Since a reg-reg move is really a reg-mem move, we must
248 enforce alignment. */
249 if (s
> 1 && (regno
% 2))
254 return (mode
== BImode
);
255 /* All other registers must be accessed in their natural sizes. */
256 if (s
== register_sizes
[regno
])
261 /* Simplify_gen_subreg() doesn't handle memory references the way we
262 need it to below, so we use this function for when we must get a
263 valid subreg in a "natural" state. */
265 rl78_subreg (enum machine_mode mode
, rtx r
, enum machine_mode omode
, int byte
)
267 if (GET_CODE (r
) == MEM
)
268 return adjust_address (r
, mode
, byte
);
270 return simplify_gen_subreg (mode
, r
, omode
, byte
);
273 /* Used by movsi. Split SImode moves into two HImode moves, using
274 appropriate patterns for the upper and lower halves of symbols. */
276 rl78_expand_movsi (rtx
*operands
)
278 rtx op00
, op02
, op10
, op12
;
280 op00
= rl78_subreg (HImode
, operands
[0], SImode
, 0);
281 op02
= rl78_subreg (HImode
, operands
[0], SImode
, 2);
282 if (GET_CODE (operands
[1]) == CONST
283 || GET_CODE (operands
[1]) == SYMBOL_REF
)
285 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (0));
286 op10
= gen_rtx_CONST (HImode
, op10
);
287 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (16));
288 op12
= gen_rtx_CONST (HImode
, op12
);
292 op10
= rl78_subreg (HImode
, operands
[1], SImode
, 0);
293 op12
= rl78_subreg (HImode
, operands
[1], SImode
, 2);
296 if (rtx_equal_p (operands
[0], operands
[1]))
298 else if (rtx_equal_p (op00
, op12
))
300 emit_move_insn (op02
, op12
);
301 emit_move_insn (op00
, op10
);
305 emit_move_insn (op00
, op10
);
306 emit_move_insn (op02
, op12
);
310 /* Used by various two-operand expanders which cannot accept all
311 operands in the "far" namespace. Force some such operands into
312 registers so that each pattern has at most one far operand. */
314 rl78_force_nonfar_2 (rtx
*operands
, rtx (*gen
)(rtx
,rtx
))
319 /* FIXME: in the future, be smarter about only doing this if the
320 other operand is also far, assuming the devirtualizer can also
322 if (rl78_far_p (operands
[0]))
324 temp_reg
= operands
[0];
325 operands
[0] = gen_reg_rtx (GET_MODE (operands
[0]));
331 emit_insn (gen (operands
[0], operands
[1]));
333 emit_move_insn (temp_reg
, operands
[0]);
337 /* Likewise, but for three-operand expanders. */
339 rl78_force_nonfar_3 (rtx
*operands
, rtx (*gen
)(rtx
,rtx
,rtx
))
344 /* FIXME: Likewise. */
345 if (rl78_far_p (operands
[1]))
347 rtx temp_reg
= gen_reg_rtx (GET_MODE (operands
[1]));
348 emit_move_insn (temp_reg
, operands
[1]);
349 operands
[1] = temp_reg
;
352 if (rl78_far_p (operands
[0]))
354 temp_reg
= operands
[0];
355 operands
[0] = gen_reg_rtx (GET_MODE (operands
[0]));
361 emit_insn (gen (operands
[0], operands
[1], operands
[2]));
363 emit_move_insn (temp_reg
, operands
[0]);
367 #undef TARGET_CAN_ELIMINATE
368 #define TARGET_CAN_ELIMINATE rl78_can_eliminate
371 rl78_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to ATTRIBUTE_UNUSED
)
376 /* Returns nonzero if the given register needs to be saved by the
379 need_to_save (int regno
)
381 if (is_interrupt_func (cfun
->decl
))
384 return 1; /* don't know what devirt will need */
386 return 0; /* don't need to save interrupt registers */
389 return df_regs_ever_live_p (regno
);
394 if (regno
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
396 if (fixed_regs
[regno
])
398 if (crtl
->calls_eh_return
)
400 if (df_regs_ever_live_p (regno
)
401 && !call_used_regs
[regno
])
406 /* We use this to wrap all emitted insns in the prologue. */
410 RTX_FRAME_RELATED_P (x
) = 1;
414 /* Compute all the frame-related fields in our machine_function
417 rl78_compute_frame_info (void)
421 cfun
->machine
->computed
= 1;
422 cfun
->machine
->framesize_regs
= 0;
423 cfun
->machine
->framesize_locals
= get_frame_size ();
424 cfun
->machine
->framesize_outgoing
= crtl
->outgoing_args_size
;
426 for (i
= 0; i
< 16; i
++)
427 if (need_to_save (i
* 2) || need_to_save (i
* 2 + 1))
429 cfun
->machine
->need_to_push
[i
] = 1;
430 cfun
->machine
->framesize_regs
+= 2;
433 cfun
->machine
->need_to_push
[i
] = 0;
435 if ((cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
) & 1)
436 cfun
->machine
->framesize_locals
++;
438 cfun
->machine
->framesize
= (cfun
->machine
->framesize_regs
439 + cfun
->machine
->framesize_locals
440 + cfun
->machine
->framesize_outgoing
);
443 /* Returns true if the provided function has the specified attribute. */
445 has_func_attr (const_tree decl
, const char * func_attr
)
447 if (decl
== NULL_TREE
)
448 decl
= current_function_decl
;
450 return lookup_attribute (func_attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
453 /* Returns true if the provided function has the "interrupt" attribute. */
455 is_interrupt_func (const_tree decl
)
457 return has_func_attr (decl
, "interrupt") || has_func_attr (decl
, "brk_interrupt");
460 /* Returns true if the provided function has the "brk_interrupt" attribute. */
462 is_brk_interrupt_func (const_tree decl
)
464 return has_func_attr (decl
, "brk_interrupt");
467 /* Check "interrupt" attributes. */
469 rl78_handle_func_attribute (tree
* node
,
472 int flags ATTRIBUTE_UNUSED
,
475 gcc_assert (DECL_P (* node
));
476 gcc_assert (args
== NULL_TREE
);
478 if (TREE_CODE (* node
) != FUNCTION_DECL
)
480 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
482 * no_add_attrs
= true;
485 /* FIXME: We ought to check that the interrupt and exception
486 handler attributes have been applied to void functions. */
490 #undef TARGET_ATTRIBUTE_TABLE
491 #define TARGET_ATTRIBUTE_TABLE rl78_attribute_table
493 /* Table of RL78-specific attributes. */
494 const struct attribute_spec rl78_attribute_table
[] =
496 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
497 affects_type_identity. */
498 { "interrupt", 0, 0, true, false, false, rl78_handle_func_attribute
,
500 { "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute
,
502 { NULL
, 0, 0, false, false, false, NULL
, false }
507 /* Break down an address RTX into its component base/index/addend
508 portions and return TRUE if the address is of a valid form, else
511 characterize_address (rtx x
, rtx
*base
, rtx
*index
, rtx
*addend
)
517 if (GET_CODE (x
) == REG
)
523 /* We sometimes get these without the CONST wrapper */
524 if (GET_CODE (x
) == PLUS
525 && GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
526 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
532 if (GET_CODE (x
) == PLUS
)
537 if (GET_CODE (*base
) != REG
538 && GET_CODE (x
) == REG
)
545 if (GET_CODE (*base
) != REG
)
548 if (GET_CODE (x
) == ZERO_EXTEND
549 && GET_CODE (XEXP (x
, 0)) == REG
)
551 *index
= XEXP (x
, 0);
556 switch (GET_CODE (x
))
559 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
560 && GET_CODE (XEXP (x
, 0)) == CONST_INT
)
583 /* Used by the Whb constraint. Match addresses that use HL+B or HL+C
586 rl78_hl_b_c_addr_p (rtx op
)
590 if (GET_CODE (op
) != PLUS
)
594 if (GET_CODE (hl
) == ZERO_EXTEND
)
600 if (GET_CODE (hl
) != REG
)
602 if (GET_CODE (bc
) != ZERO_EXTEND
)
605 if (GET_CODE (bc
) != REG
)
607 if (REGNO (hl
) != HL_REG
)
609 if (REGNO (bc
) != B_REG
&& REGNO (bc
) != C_REG
)
615 #define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
617 /* Used in various constraints and predicates to match operands in the
618 "far" address space. */
622 if (GET_CODE (x
) != MEM
)
625 fprintf(stderr
, "\033[35mrl78_far_p: "); debug_rtx(x
);
626 fprintf(stderr
, " = %d\033[0m\n", MEM_ADDR_SPACE (x
) == ADDR_SPACE_FAR
);
628 return MEM_ADDR_SPACE (x
) == ADDR_SPACE_FAR
;
631 /* Return the appropriate mode for a named address pointer. */
632 #undef TARGET_ADDR_SPACE_POINTER_MODE
633 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
634 static enum machine_mode
635 rl78_addr_space_pointer_mode (addr_space_t addrspace
)
639 case ADDR_SPACE_GENERIC
:
648 /* Return the appropriate mode for a named address address. */
649 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
650 #define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
651 static enum machine_mode
652 rl78_addr_space_address_mode (addr_space_t addrspace
)
656 case ADDR_SPACE_GENERIC
:
665 #undef TARGET_LEGITIMATE_CONSTANT_P
666 #define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant
669 rl78_is_legitimate_constant (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x ATTRIBUTE_UNUSED
)
674 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
675 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P rl78_as_legitimate_address
678 rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
,
679 bool strict ATTRIBUTE_UNUSED
, addr_space_t as ATTRIBUTE_UNUSED
)
681 rtx base
, index
, addend
;
683 if (as
== ADDR_SPACE_GENERIC
684 && GET_MODE (x
) == SImode
)
687 if (! characterize_address (x
, &base
, &index
, &addend
))
690 /* We can't extract the high/low portions of a PLUS address
691 involving a register during devirtualization, so make sure all
692 such __far addresses do not have addends. This forces GCC to do
693 the sum separately. */
694 if (addend
&& base
&& as
== ADDR_SPACE_FAR
)
699 int ir
= REGNO (index
);
700 int br
= REGNO (base
);
702 #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
703 OK (REG_IS (br
, HL_REG
) && REG_IS (ir
, B_REG
), "[hl+b]");
704 OK (REG_IS (br
, HL_REG
) && REG_IS (ir
, C_REG
), "[hl+c]");
708 if (strict
&& base
&& GET_CODE (base
) == REG
&& REGNO (base
) >= FIRST_PSEUDO_REGISTER
)
714 /* Determine if one named address space is a subset of another. */
715 #undef TARGET_ADDR_SPACE_SUBSET_P
716 #define TARGET_ADDR_SPACE_SUBSET_P rl78_addr_space_subset_p
718 rl78_addr_space_subset_p (addr_space_t subset
, addr_space_t superset
)
720 gcc_assert (subset
== ADDR_SPACE_GENERIC
|| subset
== ADDR_SPACE_FAR
);
721 gcc_assert (superset
== ADDR_SPACE_GENERIC
|| superset
== ADDR_SPACE_FAR
);
723 if (subset
== superset
)
727 return (subset
== ADDR_SPACE_GENERIC
&& superset
== ADDR_SPACE_FAR
);
730 #undef TARGET_ADDR_SPACE_CONVERT
731 #define TARGET_ADDR_SPACE_CONVERT rl78_addr_space_convert
732 /* Convert from one address space to another. */
734 rl78_addr_space_convert (rtx op
, tree from_type
, tree to_type
)
736 addr_space_t from_as
= TYPE_ADDR_SPACE (TREE_TYPE (from_type
));
737 addr_space_t to_as
= TYPE_ADDR_SPACE (TREE_TYPE (to_type
));
740 gcc_assert (from_as
== ADDR_SPACE_GENERIC
|| from_as
== ADDR_SPACE_FAR
);
741 gcc_assert (to_as
== ADDR_SPACE_GENERIC
|| to_as
== ADDR_SPACE_FAR
);
743 if (to_as
== ADDR_SPACE_GENERIC
&& from_as
== ADDR_SPACE_FAR
)
745 /* This is unpredictable, as we're truncating off usable address
748 result
= gen_reg_rtx (HImode
);
749 emit_move_insn (result
, simplify_subreg (HImode
, op
, SImode
, 0));
752 else if (to_as
== ADDR_SPACE_FAR
&& from_as
== ADDR_SPACE_GENERIC
)
754 /* This always works. */
755 result
= gen_reg_rtx (SImode
);
758 emit_move_insn (rl78_subreg (HImode
, result
, SImode
, 0), op
);
759 emit_move_insn (rl78_subreg (HImode
, result
, SImode
, 2), const0_rtx
);
766 /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */
768 rl78_regno_mode_code_ok_for_base_p (int regno
, enum machine_mode mode ATTRIBUTE_UNUSED
,
769 addr_space_t address_space ATTRIBUTE_UNUSED
,
770 int outer_code ATTRIBUTE_UNUSED
, int index_code
)
772 if (regno
< 24 && regno
>= 16)
774 if (index_code
== REG
)
775 return (regno
== HL_REG
);
776 if (regno
== C_REG
|| regno
== B_REG
|| regno
== E_REG
|| regno
== L_REG
)
781 /* Implements MODE_CODE_BASE_REG_CLASS. */
783 rl78_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED
,
784 addr_space_t address_space ATTRIBUTE_UNUSED
,
785 int outer_code ATTRIBUTE_UNUSED
,
786 int index_code ATTRIBUTE_UNUSED
)
791 /* Implements INITIAL_ELIMINATION_OFFSET. The frame layout is
792 described in the machine_Function struct definition, above. */
794 rl78_initial_elimination_offset (int from
, int to
)
796 int rv
= 0; /* as if arg to arg */
798 rl78_compute_frame_info ();
802 case STACK_POINTER_REGNUM
:
803 rv
+= cfun
->machine
->framesize_outgoing
;
804 rv
+= cfun
->machine
->framesize_locals
;
806 case FRAME_POINTER_REGNUM
:
807 rv
+= cfun
->machine
->framesize_regs
;
816 case FRAME_POINTER_REGNUM
:
818 rv
-= cfun
->machine
->framesize_regs
;
819 case ARG_POINTER_REGNUM
:
828 /* Expand the function prologue (from the prologue pattern). */
830 rl78_expand_prologue (void)
833 rtx sp
= gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
);
836 if (!cfun
->machine
->computed
)
837 rl78_compute_frame_info ();
839 if (flag_stack_usage_info
)
840 current_function_static_stack_size
= cfun
->machine
->framesize
;
842 if (is_interrupt_func (cfun
->decl
))
843 emit_insn (gen_sel_rb (GEN_INT (0)));
845 for (i
= 0; i
< 16; i
++)
846 if (cfun
->machine
->need_to_push
[i
])
851 emit_insn (gen_sel_rb (GEN_INT (need_bank
)));
854 F (emit_insn (gen_push (gen_rtx_REG (HImode
, i
*2))));
857 emit_insn (gen_sel_rb (GEN_INT (0)));
859 if (frame_pointer_needed
)
860 F (emit_move_insn (gen_rtx_REG (HImode
, FRAME_POINTER_REGNUM
),
861 gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
)));
863 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
866 int fs_byte
= (fs
> 254) ? 254 : fs
;
867 F (emit_insn (gen_subhi3 (sp
, sp
, GEN_INT (fs_byte
))));
872 /* Expand the function epilogue (from the epilogue pattern). */
874 rl78_expand_epilogue (void)
877 rtx sp
= gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
);
880 if (frame_pointer_needed
)
882 emit_move_insn (gen_rtx_REG (HImode
, STACK_POINTER_REGNUM
),
883 gen_rtx_REG (HImode
, FRAME_POINTER_REGNUM
));
887 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
890 int fs_byte
= (fs
> 254) ? 254 : fs
;
892 emit_insn (gen_addhi3 (sp
, sp
, GEN_INT (fs_byte
)));
897 for (i
= 15; i
>= 0; i
--)
898 if (cfun
->machine
->need_to_push
[i
])
900 int need_bank
= i
/ 4;
904 emit_insn (gen_sel_rb (GEN_INT (need_bank
)));
907 emit_insn (gen_pop (gen_rtx_REG (HImode
, i
* 2)));
911 emit_insn (gen_sel_rb (GEN_INT (0)));
913 if (cfun
->machine
->trampolines_used
)
914 emit_insn (gen_trampoline_uninit ());
916 if (is_brk_interrupt_func (cfun
->decl
))
917 emit_jump_insn (gen_brk_interrupt_return ());
918 else if (is_interrupt_func (cfun
->decl
))
919 emit_jump_insn (gen_interrupt_return ());
921 emit_jump_insn (gen_rl78_return ());
924 /* Likewise, for exception handlers. */
926 rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED
)
928 /* FIXME - replace this with an indirect jump with stack adjust. */
929 emit_jump_insn (gen_rl78_return ());
932 #undef TARGET_ASM_FUNCTION_PROLOGUE
933 #define TARGET_ASM_FUNCTION_PROLOGUE rl78_start_function
935 /* We don't use this to actually emit the function prologue. We use
936 this to insert a comment in the asm file describing the
939 rl78_start_function (FILE *file
, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED
)
943 if (cfun
->machine
->framesize
== 0)
945 fprintf (file
, "\t; start of function\n");
947 if (cfun
->machine
->framesize_regs
)
949 fprintf (file
, "\t; push %d:", cfun
->machine
->framesize_regs
);
950 for (i
= 0; i
< 16; i
++)
951 if (cfun
->machine
->need_to_push
[i
])
952 fprintf (file
, " %s", word_regnames
[i
*2]);
956 if (frame_pointer_needed
)
957 fprintf (file
, "\t; $fp points here (r22)\n");
959 if (cfun
->machine
->framesize_locals
)
960 fprintf (file
, "\t; locals: %d byte%s\n", cfun
->machine
->framesize_locals
,
961 cfun
->machine
->framesize_locals
== 1 ? "" : "s");
963 if (cfun
->machine
->framesize_outgoing
)
964 fprintf (file
, "\t; outgoing: %d byte%s\n", cfun
->machine
->framesize_outgoing
,
965 cfun
->machine
->framesize_outgoing
== 1 ? "" : "s");
968 /* Return an RTL describing where a function return value of type RET_TYPE
971 #undef TARGET_FUNCTION_VALUE
972 #define TARGET_FUNCTION_VALUE rl78_function_value
975 rl78_function_value (const_tree ret_type
,
976 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
977 bool outgoing ATTRIBUTE_UNUSED
)
979 enum machine_mode mode
= TYPE_MODE (ret_type
);
981 return gen_rtx_REG (mode
, 8);
984 #undef TARGET_PROMOTE_FUNCTION_MODE
985 #define TARGET_PROMOTE_FUNCTION_MODE rl78_promote_function_mode
987 static enum machine_mode
988 rl78_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
989 enum machine_mode mode
,
990 int *punsignedp ATTRIBUTE_UNUSED
,
991 const_tree funtype ATTRIBUTE_UNUSED
, int for_return ATTRIBUTE_UNUSED
)
996 /* Return an RTL expression describing the register holding a function
997 parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
998 be passed on the stack. CUM describes the previous parameters to the
999 function and NAMED is false if the parameter is part of a variable
1000 parameter list, or the last named parameter before the start of a
1001 variable parameter list. */
1003 #undef TARGET_FUNCTION_ARG
1004 #define TARGET_FUNCTION_ARG rl78_function_arg
1007 rl78_function_arg (cumulative_args_t cum_v ATTRIBUTE_UNUSED
,
1008 enum machine_mode mode ATTRIBUTE_UNUSED
,
1009 const_tree type ATTRIBUTE_UNUSED
,
1010 bool named ATTRIBUTE_UNUSED
)
1015 #undef TARGET_FUNCTION_ARG_ADVANCE
1016 #define TARGET_FUNCTION_ARG_ADVANCE rl78_function_arg_advance
1019 rl78_function_arg_advance (cumulative_args_t cum_v
, enum machine_mode mode
, const_tree type
,
1020 bool named ATTRIBUTE_UNUSED
)
1023 CUMULATIVE_ARGS
* cum
= get_cumulative_args (cum_v
);
1025 rounded_size
= ((mode
== BLKmode
)
1026 ? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
));
1027 if (rounded_size
& 1)
1029 (*cum
) += rounded_size
;
1032 #undef TARGET_FUNCTION_ARG_BOUNDARY
1033 #define TARGET_FUNCTION_ARG_BOUNDARY rl78_function_arg_boundary
1036 rl78_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED
,
1037 const_tree type ATTRIBUTE_UNUSED
)
1042 /* Supported modifier letters:
1044 A - address of a MEM
1045 S - SADDR form of a real register
1046 v - real register corresponding to a virtual register
1047 m - minus - negative of CONST_INT value.
1048 c - inverse of a conditional (NE vs EQ for example)
1050 h - bottom HI of an SI
1052 q - bottom QI of an HI
1054 e - third QI of an SI (i.e. where the ES register gets values from)
1058 /* Implements the bulk of rl78_print_operand, below. We do it this
1059 way because we need to test for a constant at the top level and
1060 insert the '#', but not test for it anywhere else as we recurse
1061 down into the operand. */
1063 rl78_print_operand_1 (FILE * file
, rtx op
, int letter
)
1067 switch (GET_CODE (op
))
1071 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1074 if (rl78_far_p (op
))
1075 fprintf(file
, "es:");
1078 op
= adjust_address (op
, HImode
, 2);
1083 op
= adjust_address (op
, HImode
, 0);
1088 op
= adjust_address (op
, QImode
, 1);
1093 op
= adjust_address (op
, QImode
, 0);
1098 op
= adjust_address (op
, QImode
, 2);
1101 if (CONSTANT_P (XEXP (op
, 0)))
1104 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1106 else if (GET_CODE (XEXP (op
, 0)) == PLUS
1107 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == SYMBOL_REF
)
1110 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1112 else if (GET_CODE (XEXP (op
, 0)) == PLUS
1113 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == REG
1114 && REGNO (XEXP (XEXP (op
, 0), 0)) == 2)
1116 rl78_print_operand_1 (file
, XEXP (XEXP (op
, 0), 1), 'u');
1118 rl78_print_operand_1 (file
, XEXP (XEXP (op
, 0), 0), 0);
1124 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1132 fprintf (file
, "%s", reg_names
[REGNO (op
) | 1]);
1133 else if (letter
== 'H')
1134 fprintf (file
, "%s", reg_names
[REGNO (op
) + 2]);
1135 else if (letter
== 'q')
1136 fprintf (file
, "%s", reg_names
[REGNO (op
) & ~1]);
1137 else if (letter
== 'e')
1138 fprintf (file
, "%s", reg_names
[REGNO (op
) + 2]);
1139 else if (letter
== 'S')
1140 fprintf (file
, "0x%x", 0xffef8 + REGNO (op
));
1141 else if (GET_MODE (op
) == HImode
1142 && ! (REGNO (op
) & ~0xfe))
1145 fprintf (file
, "%s", word_regnames
[REGNO (op
) % 8]);
1147 fprintf (file
, "%s", word_regnames
[REGNO (op
)]);
1150 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
1155 fprintf (file
, "%ld", INTVAL (op
) >> 8);
1156 else if (letter
== 'H')
1157 fprintf (file
, "%ld", INTVAL (op
) >> 16);
1158 else if (letter
== 'q')
1159 fprintf (file
, "%ld", INTVAL (op
) & 0xff);
1160 else if (letter
== 'h')
1161 fprintf (file
, "%ld", INTVAL (op
) & 0xffff);
1162 else if (letter
== 'e')
1163 fprintf (file
, "%ld", (INTVAL (op
) >> 16) & 0xff);
1164 else if (letter
== 'm')
1165 fprintf (file
, "%ld", - INTVAL (op
));
1167 fprintf(file
, "%ld", INTVAL (op
));
1171 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1176 int bits
= INTVAL (XEXP (op
, 1));
1177 int ofs
= INTVAL (XEXP (op
, 2));
1178 if (bits
== 16 && ofs
== 0)
1179 fprintf (file
, "%%lo16(");
1180 else if (bits
== 16 && ofs
== 16)
1181 fprintf (file
, "%%hi16(");
1182 else if (bits
== 8 && ofs
== 16)
1183 fprintf (file
, "%%hi8(");
1186 rl78_print_operand_1 (file
, XEXP (op
, 0), 0);
1187 fprintf (file
, ")");
1192 if (GET_CODE (XEXP (op
, 0)) == REG
)
1193 fprintf (file
, "%s", reg_names
[REGNO (XEXP (op
, 0))]);
1195 print_rtl (file
, op
);
1202 fprintf (file
, "%%hi16(");
1208 fprintf (file
, "%%lo16(");
1214 fprintf (file
, "%%hi8(");
1218 if (letter
== 'q' || letter
== 'Q')
1219 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1221 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTEND
)
1223 rl78_print_operand_1 (file
, XEXP (op
, 1), letter
);
1224 fprintf (file
, "+");
1225 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1229 rl78_print_operand_1 (file
, XEXP (op
, 0), letter
);
1230 fprintf (file
, "+");
1231 rl78_print_operand_1 (file
, XEXP (op
, 1), letter
);
1234 fprintf (file
, ")");
1241 fprintf (file
, "%%hi16(");
1247 fprintf (file
, "%%lo16(");
1253 fprintf (file
, "%%hi8(");
1257 if (letter
== 'q' || letter
== 'Q')
1258 output_operand_lossage ("q/Q modifiers invalid for symbol references");
1260 output_addr_const (file
, op
);
1262 fprintf (file
, ")");
1267 output_asm_label (op
);
1271 fprintf (file
, letter
== 'c' ? "nc" : "c");
1274 fprintf (file
, letter
== 'c' ? "h" : "nh");
1277 fprintf (file
, letter
== 'c' ? "c" : "nc");
1280 fprintf (file
, letter
== 'c' ? "nh" : "h");
1283 fprintf (file
, letter
== 'c' ? "nz" : "z");
1286 fprintf (file
, letter
== 'c' ? "z" : "nz");
1290 fprintf (file
, "(%s)", GET_RTX_NAME (GET_CODE (op
)));
1295 #undef TARGET_PRINT_OPERAND
1296 #define TARGET_PRINT_OPERAND rl78_print_operand
1299 rl78_print_operand (FILE * file
, rtx op
, int letter
)
1301 if (CONSTANT_P (op
) && letter
!= 'u')
1302 fprintf (file
, "#");
1303 rl78_print_operand_1 (file
, op
, letter
);
1306 #undef TARGET_TRAMPOLINE_INIT
1307 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
1309 /* Note that the RL78's addressing makes it very difficult to do
1310 trampolines on the stack. So, libgcc has a small pool of
1311 trampolines from which one is allocated to this task. */
1313 rl78_trampoline_init (rtx m_tramp
, tree fndecl
, rtx static_chain
)
1315 rtx mov_addr
, thunk_addr
;
1316 rtx function
= XEXP (DECL_RTL (fndecl
), 0);
1318 mov_addr
= adjust_address (m_tramp
, HImode
, 0);
1319 thunk_addr
= gen_reg_rtx (HImode
);
1321 function
= force_reg (HImode
, function
);
1322 static_chain
= force_reg (HImode
, static_chain
);
1324 emit_insn (gen_trampoline_init (thunk_addr
, function
, static_chain
));
1325 emit_move_insn (mov_addr
, thunk_addr
);
1327 cfun
->machine
->trampolines_used
= 1;
1330 #undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
1331 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS rl78_trampoline_adjust_address
1334 rl78_trampoline_adjust_address (rtx m_tramp
)
1336 rtx x
= gen_rtx_MEM (HImode
, m_tramp
);
1340 /* Expander for cbranchqi4 and cbranchhi4. RL78 is missing some of
1341 the "normal" compares, specifically, it only has unsigned compares,
1342 so we must synthesize the missing ones. */
1344 rl78_expand_compare (rtx
*operands
)
1346 /* RL78 does not have signed comparisons. We must modify the
1347 operands to be in the unsigned range, and emit an unsigned
1350 enum machine_mode mode
;
1355 switch (GET_CODE (operands
[0]))
1374 fprintf (stderr
, "\033[38;5;129mrl78_expand_compare\n");
1375 debug_rtx (operands
[0]);
1376 fprintf (stderr
, "\033[0m");
1379 mode
= GET_MODE (operands
[1]);
1380 if (mode
== VOIDmode
)
1381 mode
= GET_MODE (operands
[2]);
1382 high_bit
= GEN_INT (~0 << (GET_MODE_BITSIZE (mode
) - 1));
1384 /* 0: conditional 1,2: operands */
1385 for (i
= 1; i
<= 2; i
++)
1387 rtx r
= operands
[i
];
1389 if (GET_CODE (r
) == CONST_INT
)
1390 r
= GEN_INT (INTVAL (r
) ^ INTVAL (high_bit
));
1393 r
= gen_rtx_PLUS (mode
, operands
[i
], high_bit
);
1394 r
= copy_to_mode_reg (mode
, r
);
1399 operands
[0] = gen_rtx_fmt_ee (new_cond
, GET_MODE (operands
[0]), operands
[1], operands
[2]);
1402 fprintf (stderr
, "\033[38;5;142mrl78_expand_compare\n");
1403 debug_rtx (operands
[0]);
1404 fprintf (stderr
, "\033[0m");
1410 /* Define this to 1 if you are debugging the peephole optimizers. */
1411 #define DEBUG_PEEP 0
1413 /* Predicate used to enable the peephole2 patterns in rl78-virt.md.
1414 The default "word" size is a byte so we can effectively use all the
1415 registers, but we want to do 16-bit moves whenever possible. This
1416 function determines when such a move is an option. */
1418 rl78_peep_movhi_p (rtx
*operands
)
1423 /* (set (op0) (op1))
1424 (set (op2) (op3)) */
1427 fprintf (stderr
, "\033[33m");
1428 debug_rtx(operands
[0]);
1429 debug_rtx(operands
[1]);
1430 debug_rtx(operands
[2]);
1431 debug_rtx(operands
[3]);
1432 fprintf (stderr
, "\033[0m");
1435 if (rtx_equal_p (operands
[0], operands
[3]))
1438 fprintf (stderr
, "no peep: overlapping\n");
1443 for (i
= 0; i
< 2; i
++)
1445 if (GET_CODE (operands
[i
]) != GET_CODE (operands
[i
+2]))
1448 fprintf (stderr
, "no peep: different codes\n");
1452 if (GET_MODE (operands
[i
]) != GET_MODE (operands
[i
+2]))
1455 fprintf (stderr
, "no peep: different modes\n");
1460 switch (GET_CODE (operands
[i
]))
1464 if (REGNO (operands
[i
]) + 1 != REGNO (operands
[i
+2])
1465 || GET_MODE (operands
[i
]) != QImode
)
1468 fprintf (stderr
, "no peep: wrong regnos %d %d %d\n",
1469 REGNO (operands
[i
]), REGNO (operands
[i
+2]),
1474 if (! rl78_hard_regno_mode_ok (REGNO (operands
[i
]), HImode
))
1477 fprintf (stderr
, "no peep: reg %d not HI\n", REGNO (operands
[i
]));
1487 if (GET_MODE (operands
[i
]) != QImode
)
1489 if (MEM_ALIGN (operands
[i
]) < 16)
1491 a
= XEXP (operands
[i
], 0);
1492 if (GET_CODE (a
) == CONST
)
1494 if (GET_CODE (a
) == PLUS
)
1496 if (GET_CODE (a
) == CONST_INT
1500 fprintf (stderr
, "no peep: misaligned mem %d\n", i
);
1501 debug_rtx (operands
[i
]);
1505 m
= adjust_address (operands
[i
], QImode
, 1);
1506 if (! rtx_equal_p (m
, operands
[i
+2]))
1509 fprintf (stderr
, "no peep: wrong mem %d\n", i
);
1511 debug_rtx (operands
[i
+2]);
1519 fprintf (stderr
, "no peep: wrong rtx %d\n", i
);
1525 fprintf (stderr
, "\033[32mpeep!\033[0m\n");
1530 /* Likewise, when a peephole is activated, this function helps compute
1531 the new operands. */
1533 rl78_setup_peep_movhi (rtx
*operands
)
1537 for (i
= 0; i
< 2; i
++)
1539 switch (GET_CODE (operands
[i
]))
1542 operands
[i
+4] = gen_rtx_REG (HImode
, REGNO (operands
[i
]));
1546 operands
[i
+4] = GEN_INT ((INTVAL (operands
[i
]) & 0xff) + ((char)INTVAL (operands
[i
+2])) * 256);
1550 operands
[i
+4] = adjust_address (operands
[i
], HImode
, 0);
1560 How Devirtualization works in the RL78 GCC port
1564 The RL78 is an 8-bit port with some 16-bit operations. It has 32
1565 bytes of register space, in four banks, memory-mapped. One bank is
1566 the "selected" bank and holds the registers used for primary
1567 operations. Since the registers are memory mapped, often you can
1568 still refer to the unselected banks via memory accesses.
1572 The GCC port uses bank 0 as the "selected" registers (A, X, BC, etc)
1573 and refers to the other banks via their memory addresses, although
1574 they're treated as regular registers internally. These "virtual"
1575 registers are R8 through R23 (bank3 is reserved for asm-based
1576 interrupt handlers).
1578 There are four machine description files:
1580 rl78.md - common register-independent patterns and definitions
1581 rl78-expand.md - expanders
1582 rl78-virt.md - patterns that match BEFORE devirtualization
1583 rl78-real.md - patterns that match AFTER devirtualization
1585 At least through register allocation and reload, gcc is told that it
1586 can do pretty much anything - but may only use the virtual registers.
1587 GCC cannot properly create the varying addressing modes that the RL78
1588 supports in an efficient way.
1590 Sometime after reload, the RL78 backend "devirtualizes" the RTL. It
1591 uses the "valloc" attribute in rl78-virt.md for determining the rules
1592 by which it will replace virtual registers with real registers (or
1593 not) and how to make up addressing modes. For example, insns tagged
1594 with "ro1" have a single read-only parameter, which may need to be
1595 moved from memory/constant/vreg to a suitable real register. As part
1596 of devirtualization, a flag is toggled, disabling the rl78-virt.md
1597 patterns and enabling the rl78-real.md patterns. The new patterns'
1598 constraints are used to determine the real registers used. NOTE:
1599 patterns in rl78-virt.md essentially ignore the constrains and rely on
1600 predicates, where the rl78-real.md ones essentially ignore the
1601 predicates and rely on the constraints.
1603 The devirtualization pass is scheduled via the pass manager (despite
1604 being called "rl78_reorg") so it can be scheduled prior to var-track
1605 (the idea is to let gdb know about the new registers). Ideally, it
1606 would be scheduled right after pro/epilogue generation, so the
1607 post-reload optimizers could operate on the real registers, but when I
1608 tried that there were some issues building the target libraries.
1610 During devirtualization, a simple register move optimizer is run. It
1611 would be better to run a full CSE/propogation pass on it through, or
1612 re-run regmove, but that has not yet been attempted.
1615 #define DEBUG_ALLOC 0
1617 /* Rescans an insn to see if it's recognized again. This is done
1618 carefully to ensure that all the constraint information is accurate
1619 for the newly matched insn. */
1621 insn_ok_now (rtx insn
)
1623 INSN_CODE (insn
) = -1;
1624 if (recog (PATTERN (insn
), insn
, 0) > -1)
1626 extract_insn (insn
);
1627 if (constrain_operands (1))
1630 fprintf (stderr
, "\033[32m");
1632 fprintf (stderr
, "\033[0m");
1639 fprintf (stderr
, "\033[41;30m Unrecognized insn \033[0m\n");
1644 fprintf (stderr
, "\033[31m");
1646 fprintf (stderr
, "\033[0m");
1652 #define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__)
1653 #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__)
1654 #define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable()
1655 #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; }
1659 #define FAILED gcc_unreachable ()
1660 #define MAYBE_OK(insn) if (insn_ok_now (insn)) return;
1663 /* Registers into which we move the contents of virtual registers. */
1664 #define X gen_rtx_REG (QImode, 0)
1665 #define A gen_rtx_REG (QImode, 1)
1666 #define C gen_rtx_REG (QImode, 2)
1667 #define B gen_rtx_REG (QImode, 3)
1668 #define E gen_rtx_REG (QImode, 4)
1669 #define D gen_rtx_REG (QImode, 5)
1670 #define L gen_rtx_REG (QImode, 6)
1671 #define H gen_rtx_REG (QImode, 7)
1673 #define AX gen_rtx_REG (HImode, 0)
1674 #define BC gen_rtx_REG (HImode, 2)
1675 #define DE gen_rtx_REG (HImode, 4)
1676 #define HL gen_rtx_REG (HImode, 6)
1678 #define OP(x) (*recog_data.operand_loc[x])
1680 /* Returns TRUE if R is a virtual register. */
1682 is_virtual_register (rtx r
)
1684 return (GET_CODE (r
) == REG
1689 /* In all these alloc routines, we expect the following: the insn
1690 pattern is unshared, the insn was previously recognized and failed
1691 due to predicates or constraints, and the operand data is in
1694 static int virt_insn_was_frame
;
1696 /* Hook for all insns we emit. Re-mark them as FRAME_RELATED if
1699 EM2 (int line ATTRIBUTE_UNUSED
, rtx r
)
1702 fprintf (stderr
, "\033[36m%d: ", line
);
1704 fprintf (stderr
, "\033[0m");
1706 /*SCHED_GROUP_P (r) = 1;*/
1707 if (virt_insn_was_frame
)
1708 RTX_FRAME_RELATED_P (r
) = 1;
1712 #define EM(x) EM2 (__LINE__, x)
1714 /* Return a suitable RTX for the low half of a __far address. */
1716 rl78_lo16 (rtx addr
)
1718 if (GET_CODE (addr
) == SYMBOL_REF
1719 || GET_CODE (addr
) == CONST
)
1721 rtx r
= gen_rtx_ZERO_EXTRACT (HImode
, addr
, GEN_INT (16), GEN_INT (0));
1722 r
= gen_rtx_CONST (HImode
, r
);
1725 return rl78_subreg (HImode
, addr
, SImode
, 0);
1728 /* Return a suitable RTX for the high half's lower byte of a __far address. */
1732 if (GET_CODE (addr
) == SYMBOL_REF
1733 || GET_CODE (addr
) == CONST
)
1735 rtx r
= gen_rtx_ZERO_EXTRACT (QImode
, addr
, GEN_INT (8), GEN_INT (16));
1736 r
= gen_rtx_CONST (QImode
, r
);
1739 return rl78_subreg (QImode
, addr
, SImode
, 2);
1742 /* Copy any register values into real registers and return an RTX for
1743 the same memory, now addressed by real registers. Any needed insns
1744 are emitted before BEFORE. */
1746 transcode_memory_rtx (rtx m
, rtx newbase
, rtx before
)
1748 rtx base
, index
, addendr
;
1751 if (GET_CODE (m
) != MEM
)
1754 if (GET_MODE (XEXP (m
, 0)) == SImode
)
1756 rtx seg
= rl78_hi8 (XEXP (m
, 0));
1758 fprintf (stderr
, "setting ES:\n");
1761 emit_insn_before (EM(gen_movqi (A
, seg
)), before
);
1762 emit_insn_before (EM(gen_movqi_es (A
)), before
);
1763 m
= change_address (m
, GET_MODE (m
), rl78_lo16 (XEXP (m
, 0)));
1766 characterize_address (XEXP (m
, 0), &base
, &index
, &addendr
);
1767 gcc_assert (index
== NULL_RTX
);
1770 fprintf (stderr
, "\033[33m"); debug_rtx(m
); fprintf (stderr
, "\033[0m");
1773 if (base
== NULL_RTX
)
1776 if (addendr
&& GET_CODE (addendr
) == CONST_INT
)
1777 addend
= INTVAL (addendr
);
1779 if (REGNO (base
) == SP_REG
)
1781 if (addend
>= 0 && addend
<= 255)
1785 /* BASE should be a virtual register. We copy it to NEWBASE. If
1786 the addend is out of range for DE/HL, we use AX to compute the full
1790 || (addend
> 255 && REGNO (newbase
) != 2)
1791 || (addendr
&& GET_CODE (addendr
) != CONST_INT
))
1796 EM (emit_insn_before (gen_movhi (AX
, base
), before
));
1797 EM (emit_insn_before (gen_addhi3 (AX
, AX
, addendr
), before
));
1798 EM (emit_insn_before (gen_movhi (newbase
, AX
), before
));
1804 EM (emit_insn_before (gen_movhi (newbase
, base
), before
));
1809 base
= gen_rtx_PLUS (HImode
, base
, GEN_INT (addend
));
1812 fprintf (stderr
, "\033[33m");
1815 m
= change_address (m
, GET_MODE (m
), base
);
1818 fprintf (stderr
, "\033[0m");
1823 /* Copy SRC to accumulator (A or AX), placing any generated insns
1824 before BEFORE. Returns accumulator RTX. */
1827 move_to_acc (int opno
, rtx before
)
1830 enum machine_mode mode
= GET_MODE (src
);
1832 if (GET_CODE (src
) == REG
1836 if (mode
== VOIDmode
)
1837 mode
= recog_data
.operand_mode
[opno
];
1841 EM (emit_insn_before (gen_movqi (A
, src
), before
));
1846 EM (emit_insn_before (gen_movhi (AX
, src
), before
));
1851 /* Copy accumulator (A or AX) to DEST, placing any generated insns
1852 after AFTER. Returns accumulator RTX. */
1855 move_from_acc (rtx dest
, rtx after
)
1857 enum machine_mode mode
= GET_MODE (dest
);
1859 if (REG_P (dest
) && REGNO (dest
) < 2)
1864 EM (emit_insn_after (gen_movqi (dest
, A
), after
));
1869 EM (emit_insn_after (gen_movhi (dest
, AX
), after
));
1874 /* Copy accumulator (A or AX) to REGNO, placing any generated insns
1875 before BEFORE. Returns reg RTX. */
1878 move_acc_to_reg (rtx acc
, int regno
, rtx before
)
1880 enum machine_mode mode
= GET_MODE (acc
);
1883 reg
= gen_rtx_REG (mode
, regno
);
1887 EM (emit_insn_before (gen_movqi (reg
, A
), before
));
1892 EM (emit_insn_before (gen_movhi (reg
, AX
), before
));
1897 /* Copy SRC to X, placing any generated insns before BEFORE.
1901 move_to_x (int opno
, rtx before
)
1904 enum machine_mode mode
= GET_MODE (src
);
1907 if (mode
== VOIDmode
)
1908 mode
= recog_data
.operand_mode
[opno
];
1909 reg
= (mode
== QImode
) ? X
: AX
;
1911 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
1913 OP(opno
) = move_to_acc (opno
, before
);
1914 OP(opno
) = move_acc_to_reg (OP(opno
), X_REG
, before
);
1919 EM (emit_insn_before (gen_movqi (reg
, src
), before
));
1921 EM (emit_insn_before (gen_movhi (reg
, src
), before
));
1926 /* Copy OP(opno) to H or HL, placing any generated insns before BEFORE.
1927 Returns H/HL RTX. */
1930 move_to_hl (int opno
, rtx before
)
1932 rtx src
= OP (opno
);
1933 enum machine_mode mode
= GET_MODE (src
);
1936 if (mode
== VOIDmode
)
1937 mode
= recog_data
.operand_mode
[opno
];
1938 reg
= (mode
== QImode
) ? L
: HL
;
1940 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
1942 OP (opno
) = move_to_acc (opno
, before
);
1943 OP (opno
) = move_acc_to_reg (OP (opno
), L_REG
, before
);
1948 EM (emit_insn_before (gen_movqi (reg
, src
), before
));
1950 EM (emit_insn_before (gen_movhi (reg
, src
), before
));
1955 /* Copy OP(opno) to E or DE, placing any generated insns before BEFORE.
1956 Returns E/DE RTX. */
1959 move_to_de (int opno
, rtx before
)
1961 rtx src
= OP (opno
);
1962 enum machine_mode mode
= GET_MODE (src
);
1965 if (mode
== VOIDmode
)
1966 mode
= recog_data
.operand_mode
[opno
];
1968 reg
= (mode
== QImode
) ? E
: DE
;
1970 if (mode
== QImode
|| ! is_virtual_register (OP (opno
)))
1972 OP (opno
) = move_to_acc (opno
, before
);
1973 OP (opno
) = move_acc_to_reg (OP (opno
), E_REG
, before
);
1977 rtx move
= mode
== QImode
? gen_movqi (reg
, src
) : gen_movhi (reg
, src
);
1979 EM (emit_insn_before (move
, before
));
1985 /* Devirtualize an insn of the form (SET (op) (unop (op))). */
1987 rl78_alloc_physical_registers_op1 (rtx insn
)
1989 /* op[0] = func op[1] */
1991 /* We first try using A as the destination, then copying it
1993 if (rtx_equal_p (OP(0), OP(1)))
1996 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2000 OP(0) = transcode_memory_rtx (OP(0), BC
, insn
);
2001 OP(1) = transcode_memory_rtx (OP(1), HL
, insn
);
2006 OP(0) = move_from_acc (OP(0), insn
);
2010 /* Try copying the src to acc first, then. This is for, for
2011 example, ZERO_EXTEND or NOT. */
2012 OP(1) = move_to_acc (1, insn
);
2019 /* Devirtualize an insn of the form (SET (op) (unop (op) (op))). */
2021 rl78_alloc_physical_registers_op2 (rtx insn
)
2023 /* op[0] = op[1] func op[2] */
2024 rtx prev
= prev_nonnote_nondebug_insn (insn
);
2028 if (rtx_equal_p (OP(0), OP(1)))
2031 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2032 prev
= next_nonnote_nondebug_insn (prev
);
2033 OP(2) = transcode_memory_rtx (OP(2), HL
, insn
);
2034 prev
= prev_nonnote_nondebug_insn (prev
);
2036 else if (rtx_equal_p (OP(0), OP(2)))
2038 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2039 prev
= next_nonnote_nondebug_insn (prev
);
2041 OP(2) = transcode_memory_rtx (OP(2), HL
, insn
);
2042 prev
= prev_nonnote_nondebug_insn (prev
);
2046 OP(0) = transcode_memory_rtx (OP(0), BC
, insn
);
2047 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2048 prev
= next_nonnote_nondebug_insn (prev
);
2049 OP(2) = transcode_memory_rtx (OP(2), HL
, insn
);
2054 prev
= prev_nonnote_nondebug_insn (insn
);
2055 if (recog_data
.constraints
[1][0] == '%'
2056 && is_virtual_register (OP (1))
2057 && ! is_virtual_register (OP (2))
2058 && ! CONSTANT_P (OP (2)))
2065 /* Make a note of wether (H)L is being used. It matters
2066 because if OP(2) alsoneeds reloading, then we must take
2067 care not to corrupt HL. */
2068 hl_used
= reg_mentioned_p (L
, OP (0)) || reg_mentioned_p (L
, OP (1));
2070 OP(0) = move_from_acc (OP (0), insn
);
2071 OP(1) = move_to_acc (1, insn
);
2075 /* We have to copy op2 to HL, but that involves AX, which
2076 already has a live value. Emit it before those insns. */
2079 first
= next_nonnote_nondebug_insn (prev
);
2081 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
2084 OP (2) = hl_used
? move_to_de (2, first
) : move_to_hl (2, first
);
2091 /* Devirtualize an insn of the form (SET () (unop (op))). */
2094 rl78_alloc_physical_registers_ro1 (rtx insn
)
2097 OP(0) = transcode_memory_rtx (OP(0), BC
, insn
);
2101 OP(0) = move_to_acc (0, insn
);
2108 /* Devirtualize a compare insn. */
2110 rl78_alloc_physical_registers_cmp (rtx insn
)
2112 /* op[1] cmp_op[0] op[2] */
2113 rtx prev
= prev_nonnote_nondebug_insn (insn
);
2116 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2117 OP(2) = transcode_memory_rtx (OP(2), HL
, insn
);
2121 OP(1) = move_to_acc (1, insn
);
2125 /* We have to copy op2 to HL, but that involves the acc, which
2126 already has a live value. Emit it before those insns. */
2129 first
= next_nonnote_nondebug_insn (prev
);
2131 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
2133 OP(2) = move_to_hl (2, first
);
2140 /* Like op2, but AX = A op X. */
2142 rl78_alloc_physical_registers_umul (rtx insn
)
2144 /* op[0] = op[1] func op[2] */
2145 rtx prev
= prev_nonnote_nondebug_insn (insn
);
2148 OP(0) = transcode_memory_rtx (OP(0), BC
, insn
);
2149 OP(1) = transcode_memory_rtx (OP(1), DE
, insn
);
2150 OP(2) = transcode_memory_rtx (OP(2), HL
, insn
);
2154 if (recog_data
.constraints
[1][0] == '%'
2155 && is_virtual_register (OP(1))
2156 && !is_virtual_register (OP(2))
2157 && !CONSTANT_P (OP(2)))
2164 OP(0) = move_from_acc (OP(0), insn
);
2165 OP(1) = move_to_acc (1, insn
);
2169 /* We have to copy op2 to X, but that involves the acc, which
2170 already has a live value. Emit it before those insns. */
2173 first
= next_nonnote_nondebug_insn (prev
);
2175 for (first
= insn
; prev_nonnote_nondebug_insn (first
); first
= prev_nonnote_nondebug_insn (first
))
2177 OP(2) = move_to_x (2, first
);
2184 /* Scan all insns and devirtualize them. */
2186 rl78_alloc_physical_registers (void)
2188 /* During most of the compile, gcc is dealing with virtual
2189 registers. At this point, we need to assign physical registers
2190 to the vitual ones, and copy in/out as needed. */
2193 enum attr_valloc valloc_method
;
2195 for (insn
= get_insns (); insn
; insn
= curr
)
2199 curr
= next_nonnote_nondebug_insn (insn
);
2202 && (GET_CODE (PATTERN (insn
)) == SET
2203 || GET_CODE (PATTERN (insn
)) == CALL
)
2204 && INSN_CODE (insn
) == -1)
2206 if (GET_CODE (SET_SRC (PATTERN (insn
))) == ASM_OPERANDS
)
2208 i
= recog (PATTERN (insn
), insn
, 0);
2214 INSN_CODE (insn
) = i
;
2218 cfun
->machine
->virt_insns_ok
= 0;
2219 cfun
->machine
->real_insns_ok
= 1;
2221 for (insn
= get_insns (); insn
; insn
= curr
)
2223 curr
= insn
? next_nonnote_nondebug_insn (insn
) : NULL
;
2227 if (GET_CODE (PATTERN (insn
)) != SET
2228 && GET_CODE (PATTERN (insn
)) != CALL
)
2231 if (GET_CODE (PATTERN (insn
)) == SET
2232 && GET_CODE (SET_SRC (PATTERN (insn
))) == ASM_OPERANDS
)
2235 valloc_method
= get_attr_valloc (insn
);
2237 PATTERN (insn
)= copy_rtx_if_shared (PATTERN (insn
));
2239 if (insn_ok_now (insn
))
2242 INSN_CODE (insn
) = -1;
2244 if (RTX_FRAME_RELATED_P (insn
))
2245 virt_insn_was_frame
= 1;
2247 virt_insn_was_frame
= 0;
2249 switch (valloc_method
)
2252 rl78_alloc_physical_registers_op1 (insn
);
2255 rl78_alloc_physical_registers_op2 (insn
);
2258 rl78_alloc_physical_registers_ro1 (insn
);
2261 rl78_alloc_physical_registers_cmp (insn
);
2264 rl78_alloc_physical_registers_umul (insn
);
2267 /* Macro that clobbers AX */
2272 fprintf (stderr
, "\033[0m");
2276 /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN.
2277 This function scans for uses of registers; the last use (i.e. first
2278 encounter when scanning backwards) triggers a REG_DEAD note if the
2279 reg was previously in DEAD[]. */
2281 rl78_note_reg_uses (char *dead
, rtx s
, rtx insn
)
2290 code
= GET_CODE (s
);
2294 /* Compare registers by number. */
2299 fprintf (dump_file
, "note use reg %d size %d on insn %d\n",
2300 r
, GET_MODE_SIZE (GET_MODE (s
)), INSN_UID (insn
));
2301 print_rtl_single (dump_file
, s
);
2304 add_reg_note (insn
, REG_DEAD
, gen_rtx_REG (GET_MODE (s
), r
));
2305 for (i
= 0; i
< GET_MODE_SIZE (GET_MODE (s
)); i
++)
2309 /* These codes have no constituent expressions
2320 /* These are kept unique for a given value. */
2327 fmt
= GET_RTX_FORMAT (code
);
2329 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2334 for (j
= XVECLEN (s
, i
) - 1; j
>= 0; j
--)
2335 rl78_note_reg_uses (dead
, XVECEXP (s
, i
, j
), insn
);
2337 else if (fmt
[i
] == 'e')
2338 rl78_note_reg_uses (dead
, XEXP (s
, i
), insn
);
2342 /* Like the previous function, but scan for SETs instead. */
2344 rl78_note_reg_set (char *dead
, rtx d
, rtx insn
)
2348 if (GET_CODE (d
) != REG
)
2353 add_reg_note (insn
, REG_UNUSED
, gen_rtx_REG (GET_MODE (d
), r
));
2355 fprintf (dump_file
, "note set reg %d size %d\n", r
, GET_MODE_SIZE (GET_MODE (d
)));
2356 for (i
= 0; i
< GET_MODE_SIZE (GET_MODE (d
)); i
++)
2360 /* This is a rather crude register death pass. Death status is reset
2361 at every jump or call insn. */
2363 rl78_calculate_death_notes (void)
2365 char dead
[FIRST_PSEUDO_REGISTER
];
2369 memset (dead
, 0, sizeof (dead
));
2371 for (insn
= get_last_insn ();
2373 insn
= prev_nonnote_nondebug_insn (insn
))
2377 fprintf (dump_file
, "\n--------------------------------------------------");
2378 fprintf (dump_file
, "\nDead:");
2379 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2381 fprintf(dump_file
, " %s", reg_names
[i
]);
2382 fprintf (dump_file
, "\n");
2383 print_rtl_single (dump_file
, insn
);
2386 switch (GET_CODE (insn
))
2390 switch (GET_CODE (p
))
2395 rl78_note_reg_set (dead
, d
, insn
);
2396 rl78_note_reg_uses (dead
, s
, insn
);
2400 rl78_note_reg_uses (dead
, p
, insn
);
2409 if (INSN_CODE (insn
) == CODE_FOR_rl78_return
)
2411 memset (dead
, 1, sizeof (dead
));
2412 /* We expect a USE just prior to this, which will mark
2413 the actual return registers. The USE will have a
2414 death note, but we aren't going to be modifying it
2419 memset (dead
, 0, sizeof (dead
));
2426 print_rtl_single (dump_file
, insn
);
2430 /* Helper function to reset the origins in RP and the age in AGE for
2433 reset_origins (int *rp
, int *age
)
2436 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2443 /* The idea behind this optimization is to look for cases where we
2444 move data from A to B to C, and instead move from A to B, and A to
2445 C. If B is a virtual register or memory, this is a big win on its
2446 own. If B turns out to be unneeded after this, it's a bigger win.
2447 For each register, we try to determine where it's value originally
2448 came from, if it's propogated purely through moves (and not
2449 computes). The ORIGINS[] array has the regno for the "origin" of
2450 the value in the [regno] it's indexed by. */
2452 rl78_propogate_register_origins (void)
2454 int origins
[FIRST_PSEUDO_REGISTER
];
2455 int age
[FIRST_PSEUDO_REGISTER
];
2457 rtx insn
, ninsn
= NULL_RTX
;
2460 reset_origins (origins
, age
);
2462 for (insn
= get_insns (); insn
; insn
= ninsn
)
2464 ninsn
= next_nonnote_nondebug_insn (insn
);
2468 fprintf (dump_file
, "\n");
2469 fprintf (dump_file
, "Origins:");
2470 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2471 if (origins
[i
] != i
)
2472 fprintf (dump_file
, " r%d=r%d", i
, origins
[i
]);
2473 fprintf (dump_file
, "\n");
2474 print_rtl_single (dump_file
, insn
);
2477 switch (GET_CODE (insn
))
2483 reset_origins (origins
, age
);
2490 pat
= PATTERN (insn
);
2492 if (GET_CODE (pat
) == PARALLEL
)
2494 rtx clobber
= XVECEXP (pat
, 0, 1);
2495 pat
= XVECEXP (pat
, 0, 0);
2496 if (GET_CODE (clobber
) == CLOBBER
)
2498 int cr
= REGNO (XEXP (clobber
, 0));
2499 int mb
= GET_MODE_SIZE (GET_MODE (XEXP (clobber
, 0)));
2501 fprintf (dump_file
, "reset origins of %d regs at %d\n", mb
, cr
);
2502 for (i
= 0; i
< mb
; i
++)
2504 origins
[cr
+ i
] = cr
+ i
;
2512 if (GET_CODE (pat
) == SET
)
2514 rtx src
= SET_SRC (pat
);
2515 rtx dest
= SET_DEST (pat
);
2516 int mb
= GET_MODE_SIZE (GET_MODE (dest
));
2518 if (GET_CODE (dest
) == REG
)
2520 int dr
= REGNO (dest
);
2522 if (GET_CODE (src
) == REG
)
2524 int sr
= REGNO (src
);
2526 int best_age
, best_reg
;
2528 /* See if the copy is not needed. */
2529 for (i
= 0; i
< mb
; i
++)
2530 if (origins
[dr
+ i
] != origins
[sr
+ i
])
2535 fprintf (dump_file
, "deleting because dest already has correct value\n");
2540 if (dr
< 8 || sr
>= 8)
2546 /* See if the copy can be made from another
2547 bank 0 register instead, instead of the
2548 virtual src register. */
2549 for (ar
= 0; ar
< 8; ar
+= mb
)
2552 for (i
= 0; i
< mb
; i
++)
2553 if (origins
[ar
+ i
] != origins
[sr
+ i
])
2556 /* The chip has some reg-reg move limitations. */
2557 if (mb
== 1 && dr
> 3)
2562 if (best_age
== -1 || best_age
> age
[sr
+ i
])
2564 best_age
= age
[sr
+ i
];
2572 /* FIXME: copy debug info too. */
2573 SET_SRC (pat
) = gen_rtx_REG (GET_MODE (src
), best_reg
);
2578 for (i
= 0; i
< mb
; i
++)
2580 origins
[dr
+ i
] = origins
[sr
+ i
];
2581 age
[dr
+ i
] = age
[sr
+ i
] + 1;
2586 /* The destination is computed, its origin is itself. */
2588 fprintf (dump_file
, "resetting origin of r%d for %d byte%s\n",
2589 dr
, mb
, mb
== 1 ? "" : "s");
2590 for (i
= 0; i
< mb
; i
++)
2592 origins
[dr
+ i
] = dr
+ i
;
2597 /* Any registers marked with that reg as an origin are reset. */
2598 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2599 if (origins
[i
] >= dr
&& origins
[i
] < dr
+ mb
)
2606 /* Special case - our ADDSI3 macro uses AX */
2607 if (get_attr_valloc (insn
) == VALLOC_MACAX
)
2610 fprintf (dump_file
, "Resetting origin of AX for macro.\n");
2611 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2612 if (i
<= 1 || origins
[i
] <= 1)
2619 if (GET_CODE (src
) == ASHIFT
2620 || GET_CODE (src
) == ASHIFTRT
2621 || GET_CODE (src
) == LSHIFTRT
)
2623 rtx count
= XEXP (src
, 1);
2624 if (GET_CODE (count
) == REG
)
2626 /* Special case - our pattern clobbers the count register. */
2627 int r
= REGNO (count
);
2629 fprintf (dump_file
, "Resetting origin of r%d for shift.\n", r
);
2630 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2631 if (i
== r
|| origins
[i
] == r
)
2643 /* Remove any SETs where the destination is unneeded. */
2645 rl78_remove_unused_sets (void)
2647 rtx insn
, ninsn
= NULL_RTX
;
2650 for (insn
= get_insns (); insn
; insn
= ninsn
)
2652 ninsn
= next_nonnote_nondebug_insn (insn
);
2654 if ((insn
= single_set (insn
)) == NULL_RTX
)
2657 dest
= SET_DEST (insn
);
2659 if (GET_CODE (dest
) != REG
|| REGNO (dest
) > 23)
2662 if (find_regno_note (insn
, REG_UNUSED
, REGNO (dest
)))
2667 #undef xTARGET_MACHINE_DEPENDENT_REORG
2668 #define xTARGET_MACHINE_DEPENDENT_REORG rl78_reorg
2670 /* This is the top of the devritualization pass. */
2674 rl78_alloc_physical_registers ();
2678 fprintf (dump_file
, "\n================DEVIRT:=AFTER=ALLOC=PHYSICAL=REGISTERS================\n");
2679 print_rtl_with_bb (dump_file
, get_insns (), 0);
2682 rl78_propogate_register_origins ();
2683 rl78_calculate_death_notes ();
2687 fprintf (dump_file
, "\n================DEVIRT:=AFTER=PROPOGATION=============================\n");
2688 print_rtl_with_bb (dump_file
, get_insns (), 0);
2689 fprintf (dump_file
, "\n======================================================================\n");
2692 rl78_remove_unused_sets ();
2694 /* The code after devirtualizing has changed so much that at this point
2695 we might as well just rescan everything. Note that
2696 df_rescan_all_insns is not going to help here because it does not
2697 touch the artificial uses and defs. */
2698 df_finish_pass (true);
2700 df_live_add_problem ();
2701 df_scan_alloc (NULL
);
2708 #undef TARGET_RETURN_IN_MEMORY
2709 #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory
2712 rl78_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
2714 const HOST_WIDE_INT size
= int_size_in_bytes (type
);
2715 return (size
== -1 || size
> 8);
2719 struct gcc_target targetm
= TARGET_INITIALIZER
;
2721 #include "gt-rl78.h"