200x-xx-xx Kazu Hirata <kazu@codesourcery.com> Richard Sandiford <richard@codesourcery.com>
gcc/ 200x-xx-xx Kazu Hirata <kazu@codesourcery.com> Richard Sandiford <richard@codesourcery.com> * config/m68k/m68k-protos.h (m68k_interrupt_function_p): Declare. (m68k_movem_pattern_p, m68k_output_movem): Likewise. (m68k_expand_prologue, m68k_expand_epilogue): Likewise. * config/m68k/m68k.h (EPILOGUE_USES): Define. Treat all registers as being live on exit from an interrupt function. (PRINT_OPERAND_PUNCT_VALID_P): Return true for '?'. * config/m68k/m68k.c (MIN_MOVEM_REGS, MIN_FMOVEM_REGS): New macros. (m68k_frame): Remove reg_rev_mask and fpu_rev_mask. (TARGET_ASM_FUNCTION_PROLOGUE, TARGET_ASM_FUNCTION_EPILOGUE): Delete. (m68k_interrupt_function_p): Globalize. (m68k_compute_frame_layout): Remove reverse mask code. (m68k_emit_movem, m68k_set_frame_related): New functions. (m68k_output_function_prologue): Delete in favor of... (m68k_expand_prologue): ...this new function. (m68k_output_function_epilogue): Delete in favor of... (m68k_expand_epilogue): ...this new function. (m68k_split_offset, m68k_movem_pattern_p, m68k_output_movem): New functions. (print_operand): Handle %?. * config/m68k/m68k.md (UNSPEC_SIN, UNSPEC_COS): Remove excess space. (UNSPEC_GOT, A1_REG, PIC_REG, FP0_REG): New constants. (prologue, epilogue): New patterns. (return): Turn into a define_expand. (*return): New pattern, derived from old "return" pattern. Use rte rather than rts for interrupt functions. Only use rtd if the pop count is nonzero. (*m68k_store_multiple, *m68k_store_multiple_automod): New patterns. (*m68k_load_multiple, *m68k_load_multiple_automod): Likewise. (link, *link, unlink, *unlink, load_got): Likewise. Co-Authored-By: Richard Sandiford <richard@codesourcery.com> From-SVN: r122605
This commit is contained in:
parent
fc2241eb94
commit
a40ed0f310
|
@ -1,3 +1,36 @@
|
|||
2007-03-06 Kazu Hirata <kazu@codesourcery.com>
|
||||
Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* config/m68k/m68k-protos.h (m68k_interrupt_function_p): Declare.
|
||||
(m68k_movem_pattern_p, m68k_output_movem): Likewise.
|
||||
(m68k_expand_prologue, m68k_expand_epilogue): Likewise.
|
||||
* config/m68k/m68k.h (EPILOGUE_USES): Define. Treat all registers
|
||||
as being live on exit from an interrupt function.
|
||||
(PRINT_OPERAND_PUNCT_VALID_P): Return true for '?'.
|
||||
* config/m68k/m68k.c (MIN_MOVEM_REGS, MIN_FMOVEM_REGS): New macros.
|
||||
(m68k_frame): Remove reg_rev_mask and fpu_rev_mask.
|
||||
(TARGET_ASM_FUNCTION_PROLOGUE, TARGET_ASM_FUNCTION_EPILOGUE): Delete.
|
||||
(m68k_interrupt_function_p): Globalize.
|
||||
(m68k_compute_frame_layout): Remove reverse mask code.
|
||||
(m68k_emit_movem, m68k_set_frame_related): New functions.
|
||||
(m68k_output_function_prologue): Delete in favor of...
|
||||
(m68k_expand_prologue): ...this new function.
|
||||
(m68k_output_function_epilogue): Delete in favor of...
|
||||
(m68k_expand_epilogue): ...this new function.
|
||||
(m68k_split_offset, m68k_movem_pattern_p, m68k_output_movem): New
|
||||
functions.
|
||||
(print_operand): Handle %?.
|
||||
* config/m68k/m68k.md (UNSPEC_SIN, UNSPEC_COS): Remove excess space.
|
||||
(UNSPEC_GOT, A1_REG, PIC_REG, FP0_REG): New constants.
|
||||
(prologue, epilogue): New patterns.
|
||||
(return): Turn into a define_expand.
|
||||
(*return): New pattern, derived from old "return" pattern. Use rte
|
||||
rather than rts for interrupt functions. Only use rtd if the pop
|
||||
count is nonzero.
|
||||
(*m68k_store_multiple, *m68k_store_multiple_automod): New patterns.
|
||||
(*m68k_load_multiple, *m68k_load_multiple_automod): Likewise.
|
||||
(link, *link, unlink, *unlink, load_got): Likewise.
|
||||
|
||||
2007-03-06 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
PR target/23482
|
||||
|
|
|
@ -21,6 +21,7 @@ Boston, MA 02110-1301, USA. */
|
|||
/* Define functions defined in aux-output.c and used in templates. */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern bool m68k_interrupt_function_p (tree);
|
||||
extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to);
|
||||
|
||||
extern void split_di (rtx[], int, rtx[], rtx[]);
|
||||
|
@ -61,12 +62,16 @@ extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
|
|||
extern rtx m68k_libcall_value (enum machine_mode);
|
||||
extern rtx m68k_function_value (tree, tree);
|
||||
extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
|
||||
extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool);
|
||||
extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern bool m68k_regno_mode_ok (int, enum machine_mode);
|
||||
extern int flags_in_68881 (void);
|
||||
extern void m68k_expand_prologue (void);
|
||||
extern bool m68k_use_return_insn (void);
|
||||
extern void m68k_expand_epilogue (void);
|
||||
extern void override_options (void);
|
||||
extern const char *m68k_cpp_cpu_ident (const char *);
|
||||
extern const char *m68k_cpp_cpu_family (const char *);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -987,6 +987,10 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
|
|||
/* Before the prologue, the top of the frame is at 4(%sp). */
|
||||
#define INCOMING_FRAME_SP_OFFSET 4
|
||||
|
||||
/* All registers are live on exit from an interrupt routine. */
|
||||
#define EPILOGUE_USES(REGNO) \
|
||||
(reload_completed && m68k_interrupt_function_p (current_function_decl))
|
||||
|
||||
/* Describe how we implement __builtin_eh_return. */
|
||||
#define EH_RETURN_DATA_REGNO(N) \
|
||||
((N) < 2 ? (N) : INVALID_REGNUM)
|
||||
|
@ -1123,6 +1127,7 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
|
|||
'$' for the letter `s' in an op code, but only on the 68040.
|
||||
'&' for the letter `d' in an op code, but only on the 68040.
|
||||
'/' for register prefix needed by longlong.h.
|
||||
'?' for m68k_library_id_string
|
||||
|
||||
'b' for byte insn (no effect, on the Sun; this is for the ISI).
|
||||
'd' to force memory addressing to be absolute, not relative.
|
||||
|
@ -1133,7 +1138,7 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
|
|||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '.' || (CODE) == '#' || (CODE) == '-' \
|
||||
|| (CODE) == '+' || (CODE) == '@' || (CODE) == '!' \
|
||||
|| (CODE) == '$' || (CODE) == '&' || (CODE) == '/')
|
||||
|| (CODE) == '$' || (CODE) == '&' || (CODE) == '/' || (CODE) == '?')
|
||||
|
||||
|
||||
/* See m68k.c for the m68k specific codes. */
|
||||
|
|
|
@ -112,8 +112,9 @@
|
|||
;; UNSPEC usage:
|
||||
|
||||
(define_constants
|
||||
[(UNSPEC_SIN 1)
|
||||
(UNSPEC_COS 2)
|
||||
[(UNSPEC_SIN 1)
|
||||
(UNSPEC_COS 2)
|
||||
(UNSPEC_GOT 3)
|
||||
])
|
||||
|
||||
;; UNSPEC_VOLATILE usage:
|
||||
|
@ -126,7 +127,10 @@
|
|||
(define_constants
|
||||
[(D0_REG 0)
|
||||
(A0_REG 8)
|
||||
(A1_REG 9)
|
||||
(PIC_REG 13)
|
||||
(SP_REG 15)
|
||||
(FP0_REG 16)
|
||||
])
|
||||
|
||||
(include "predicates.md")
|
||||
|
@ -6756,15 +6760,158 @@
|
|||
""
|
||||
"nop")
|
||||
|
||||
(define_expand "prologue"
|
||||
[(const_int 0)]
|
||||
""
|
||||
{
|
||||
m68k_expand_prologue ();
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "epilogue"
|
||||
[(return)]
|
||||
""
|
||||
{
|
||||
m68k_expand_epilogue ();
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Used for frameless functions which save no regs and allocate no locals.
|
||||
(define_insn "return"
|
||||
(define_expand "return"
|
||||
[(return)]
|
||||
"m68k_use_return_insn ()"
|
||||
"")
|
||||
|
||||
(define_insn "*return"
|
||||
[(return)]
|
||||
""
|
||||
{
|
||||
if (current_function_pops_args == 0)
|
||||
if (m68k_interrupt_function_p (current_function_decl))
|
||||
return "rte";
|
||||
else if (current_function_pops_args)
|
||||
{
|
||||
operands[0] = GEN_INT (current_function_pops_args);
|
||||
return "rtd %0";
|
||||
}
|
||||
else
|
||||
return "rts";
|
||||
operands[0] = GEN_INT (current_function_pops_args);
|
||||
return "rtd %0";
|
||||
})
|
||||
|
||||
(define_insn "*m68k_store_multiple"
|
||||
[(match_parallel 0 "" [(match_operand 1 "")])]
|
||||
"m68k_movem_pattern_p (operands[0], NULL, 0, true)"
|
||||
{
|
||||
return m68k_output_movem (operands, operands[0], 0, true);
|
||||
})
|
||||
|
||||
(define_insn "*m68k_store_multiple_automod"
|
||||
[(match_parallel 0 ""
|
||||
[(set (match_operand:SI 1 "register_operand" "=a")
|
||||
(plus:SI (match_operand:SI 2 "register_operand" "1")
|
||||
(match_operand:SI 3 "const_int_operand")))])]
|
||||
"m68k_movem_pattern_p (operands[0], operands[1], INTVAL (operands[3]), true)"
|
||||
{
|
||||
return m68k_output_movem (operands, operands[0], INTVAL (operands[3]), true);
|
||||
})
|
||||
|
||||
(define_insn "*m68k_load_multiple"
|
||||
[(match_parallel 0 "" [(match_operand 1 "")])]
|
||||
"m68k_movem_pattern_p (operands[0], NULL, 0, false)"
|
||||
{
|
||||
return m68k_output_movem (operands, operands[0], 0, false);
|
||||
})
|
||||
|
||||
(define_insn "*m68k_load_multiple_automod"
|
||||
[(match_parallel 0 ""
|
||||
[(set (match_operand:SI 1 "register_operand" "=a")
|
||||
(plus:SI (match_operand:SI 2 "register_operand" "1")
|
||||
(match_operand:SI 3 "const_int_operand")))])]
|
||||
"m68k_movem_pattern_p (operands[0], operands[1],
|
||||
INTVAL (operands[3]), false)"
|
||||
{
|
||||
return m68k_output_movem (operands, operands[0],
|
||||
INTVAL (operands[3]), false);
|
||||
})
|
||||
|
||||
(define_expand "link"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand")
|
||||
(plus:SI (reg:SI SP_REG) (const_int -4)))
|
||||
(set (match_dup 2)
|
||||
(match_dup 0))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (reg:SI SP_REG)
|
||||
(match_operand:SI 1 "const_int_operand")))])]
|
||||
"TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
|
||||
{
|
||||
operands[2] = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, -4));
|
||||
})
|
||||
|
||||
(define_insn "*link"
|
||||
[(set (match_operand:SI 0 "register_operand" "+r")
|
||||
(plus:SI (reg:SI SP_REG) (const_int -4)))
|
||||
(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
|
||||
(match_dup 0))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (reg:SI SP_REG)
|
||||
(match_operand:SI 1 "const_int_operand")))]
|
||||
"TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
|
||||
{
|
||||
operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
|
||||
if (!MOTOROLA)
|
||||
return "link %0,%1";
|
||||
else if (INTVAL (operands[1]) >= -0x8000)
|
||||
return "link.w %0,%1";
|
||||
else
|
||||
return "link.l %0,%1";
|
||||
})
|
||||
|
||||
(define_expand "unlink"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand")
|
||||
(match_dup 1))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (match_dup 0)
|
||||
(const_int 4)))])]
|
||||
""
|
||||
{
|
||||
operands[1] = gen_frame_mem (SImode, copy_rtx (operands[0]));
|
||||
})
|
||||
|
||||
(define_insn "*unlink"
|
||||
[(set (match_operand:SI 0 "register_operand" "+r")
|
||||
(mem:SI (match_dup 0)))
|
||||
(set (reg:SI SP_REG)
|
||||
(plus:SI (match_dup 0)
|
||||
(const_int 4)))]
|
||||
""
|
||||
"unlk %0")
|
||||
|
||||
(define_insn "load_got"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(const_int 0)] UNSPEC_GOT))]
|
||||
""
|
||||
{
|
||||
if (TARGET_ID_SHARED_LIBRARY)
|
||||
{
|
||||
operands[1] = gen_rtx_REG (Pmode, PIC_REG);
|
||||
return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
|
||||
}
|
||||
else if (MOTOROLA)
|
||||
{
|
||||
if (TARGET_COLDFIRE)
|
||||
/* Load the full 32-bit PC-relative offset of
|
||||
_GLOBAL_OFFSET_TABLE_ into the PIC register, then use it to
|
||||
calculate the absolute value. The offset and "lea"
|
||||
operation word together occupy 6 bytes. */
|
||||
return ("move.l #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t"
|
||||
"lea (-6, %%pc, %0), %0");
|
||||
else
|
||||
return "lea (%%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %0";
|
||||
}
|
||||
else
|
||||
return ("movel #_GLOBAL_OFFSET_TABLE_, %0\n\t"
|
||||
"lea %%pc@(0,%0:l),%0");
|
||||
})
|
||||
|
||||
(define_insn "indirect_jump"
|
||||
|
|
Loading…
Reference in New Issue