aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/m68hc11
diff options
context:
space:
mode:
authorciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-14 07:14:03 +0000
committerciceron <ciceron@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-14 07:14:03 +0000
commit230afcbe214c4e789dbf7541b2efe5a27aade837 (patch)
tree68e7163ba12d60d0805008ee763d28f913df3bcb /gcc/config/m68hc11
parent5934ea7aeb031c78b74123f5e7da0d10f436e094 (diff)
* doc/invoke.texi: Document -mlong-calls for 68HC12.
* config/m68hc11/m68hc11.h (CPP_SPEC): Pass -D__USE_RTC__ when -mlong-calls is specified. (ASM_DECLARE_FUNCTION_NAME): Define to generate .far and .interrupt assembler directives. (TARGET_LONG_CALL, MASK_LONG_CALL): Declare. (TARGET_SWITCHES): Add -mlong-calls options. (current_function_far): Declare. * config/m68hc11/m68hc11.c (m68hc11_initial_elimination_offset): Take into account the page register saved on the stack. (m68hc11_override_options): Take into account -mlong-calls option. (m68hc11_asm_file_start): Put a mode for the ELF flags ABI. * config/m68hc11/m68hc11.md ("*return_32bit"): Return rtc if the function is going to be in 68HC12 banked memory (-mlong-calls). ("*return_16bit"): Likewise. ("*return_void"): Likewise. ("call", "call_value"): Use call for a far function call. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56275 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/m68hc11')
-rw-r--r--gcc/config/m68hc11/m68hc11.c17
-rw-r--r--gcc/config/m68hc11/m68hc11.h49
-rw-r--r--gcc/config/m68hc11/m68hc11.md14
3 files changed, 74 insertions, 6 deletions
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 1c85ca592a9..d52289fc314 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -101,6 +101,10 @@ int current_function_interrupt;
/* Set to 1 by expand_prologue() when the function is a trap handler. */
int current_function_trap;
+/* Set to 1 when the current function is placed in 68HC12 banked
+ memory and must return with rtc. */
+int current_function_far;
+
/* Min offset that is valid for the indirect addressing mode. */
HOST_WIDE_INT m68hc11_min_offset = 0;
@@ -283,6 +287,9 @@ m68hc11_override_options ()
target_flags |= MASK_NO_DIRECT_MODE;
if (m68hc11_soft_reg_count == 0)
m68hc11_soft_reg_count = "0";
+
+ if (TARGET_LONG_CALLS)
+ current_function_far = 1;
}
return 0;
}
@@ -1277,6 +1284,11 @@ m68hc11_initial_elimination_offset (from, to)
trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE;
if (trap_handler && from == ARG_POINTER_REGNUM)
size = 7;
+
+ /* For a function using 'call/rtc' we must take into account the
+ page register which is pushed in the call. */
+ else if (current_function_far && from == ARG_POINTER_REGNUM)
+ size = 1;
else
size = 0;
@@ -5500,6 +5512,11 @@ m68hc11_asm_file_start (out, main_file)
print_options (out);
fprintf (out, ";;;-----------------------------------------\n");
output_file_directive (out, main_file);
+
+ if (TARGET_SHORT)
+ fprintf (out, "\t.mode mshort\n");
+ else
+ fprintf (out, "\t.mode mlong\n");
}
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 5a9fc529c64..32a9b6351ef 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -66,7 +66,8 @@ Note:
%{!mshort:-D__INT__=32}\
%{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\
%{!m68hc12:-Dmc6811 -DMC6811 -Dmc68hc11}\
- %{fshort-double:-D__HAVE_SHORT_DOUBLE__}"
+ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}\
+ %{mlong-calls:-D__USE_RTC__}"
#endif
#undef STARTFILE_SPEC
@@ -119,6 +120,7 @@ extern short *reg_renumber; /* def in local_alloc.c */
#define MASK_M6811 0010
#define MASK_M6812 0020
#define MASK_NO_DIRECT_MODE 0040
+#define MASK_LONG_CALLS 0200
#define TARGET_OP_TIME (optimize && optimize_size == 0)
#define TARGET_SHORT (target_flags & MASK_SHORT)
@@ -127,6 +129,7 @@ extern short *reg_renumber; /* def in local_alloc.c */
#define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC)
#define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE)
#define TARGET_RELAX (TARGET_NO_DIRECT_MODE)
+#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
/* Default target_flags if no switches specified. */
#ifndef TARGET_DEFAULT
@@ -159,6 +162,10 @@ extern short *reg_renumber; /* def in local_alloc.c */
N_("Auto pre/post decrement increment allowed")}, \
{ "noauto-incdec", - MASK_AUTO_INC_DEC, \
N_("Auto pre/post decrement increment not allowed")}, \
+ { "long-calls", MASK_LONG_CALLS, \
+ N_("Use call and rtc for function calls and returns")}, \
+ { "nolong-calls", - MASK_LONG_CALLS, \
+ N_("Use jsr and rts for function calls and returns")}, \
{ "relax", MASK_NO_DIRECT_MODE, \
N_("Do not use direct addressing mode for soft registers")},\
{ "68hc11", MASK_M6811, \
@@ -1549,6 +1556,45 @@ do { \
no longer contain unusual constructs. */
#define ASM_APP_OFF "; End of inline assembler code\n#NO_APP\n"
+/* Write the extra assembler code needed to declare a function properly.
+ Some svr4 assemblers need to also have something extra said about the
+ function's return value. We allow for that here.
+
+ For 68HC12 we mark functions that return with 'rtc'. The linker
+ will ensure that a 'call' is really made (instead of 'jsr').
+ The debugger needs this information to correctly compute the stack frame.
+
+ For 68HC11/68HC12 we also mark interrupt handlers for gdb to
+ compute the correct stack frame. */
+
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ fprintf (FILE, "%s", TYPE_ASM_OP); \
+ assemble_name (FILE, NAME); \
+ putc (',', FILE); \
+ fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
+ putc ('\n', FILE); \
+ \
+ if (TARGET_M6812 && current_function_far) \
+ { \
+ fprintf (FILE, "\t.far\t"); \
+ assemble_name (FILE, NAME); \
+ putc ('\n', FILE); \
+ } \
+ else if (current_function_interrupt \
+ || current_function_trap) \
+ { \
+ fprintf (FILE, "\t.interrupt\t"); \
+ assemble_name (FILE, NAME); \
+ putc ('\b', FILE); \
+ } \
+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
+ ASM_OUTPUT_LABEL(FILE, NAME); \
+ } \
+ while (0)
+
/* Output #ident as a .ident. */
/* output external reference */
@@ -1703,3 +1749,4 @@ extern int debug_m6811;
extern int z_replacement_completed;
extern int current_function_interrupt;
extern int current_function_trap;
+extern int current_function_far;
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index da17dd6db4f..3c0f197e967 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -6279,12 +6279,14 @@
""
"*
{
+ int far_call = current_function_far;
+
if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{
if (SYMBOL_REF_FLAG (XEXP (operands[0], 0)) == 1)
return \"swi\";
else
- return \"bsr\\t%0\";
+ return far_call ? \"call\\t%0\" : \"bsr\\t%0\";
}
else
{
@@ -6299,12 +6301,14 @@
""
"*
{
+ int far_call = current_function_far;
+
if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{
if (SYMBOL_REF_FLAG (XEXP (operands[1], 0)) == 1)
return \"swi\";
else
- return \"bsr\\t%1\";
+ return far_call ? \"call\\t%1\" : \"bsr\\t%1\";
}
else
{
@@ -6418,7 +6422,7 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return \"rts\";
+ return current_function_far ? \"rtc\" : \"rts\";
}")
(define_insn "*return_16bit"
@@ -6435,7 +6439,7 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return \"rts\";
+ return current_function_far ? \"rtc\" : \"rts\";
}")
(define_insn "*return_32bit"
@@ -6452,7 +6456,7 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return \"rts\";
+ return current_function_far ? \"rtc\" : \"rts\";
}")
(define_insn "indirect_jump"