aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Carrez <stcarrez@nerim.fr>2003-03-24 23:26:05 +0100
committerStephane Carrez <ciceron@gcc.gnu.org>2003-03-24 23:26:05 +0100
commitdbcedbc4b7380379398d655d332176c84b13f4f9 (patch)
tree0fb3f4bd3ccb2feadfa864ab69fa1909f3ae2c12
parenteea5120f8227183584f4041629cd7a69055ba467 (diff)
downloadgcc-dbcedbc4b7380379398d655d332176c84b13f4f9.zip
gcc-dbcedbc4b7380379398d655d332176c84b13f4f9.tar.gz
gcc-dbcedbc4b7380379398d655d332176c84b13f4f9.tar.bz2
t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and _return_far
* config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and _return_far (MULTILIB_OPTIONS): Don't multilib on -mlong-calls. (MULTILIB_EXCEPTIONS): Likewise. * config/m68hc11/m68hc11.md ("call"): Support far calls for 68HC11 by calling some board support routine. ("call_value"): Likewise. ("*return_void"): Likewise for return. ("*return_16bit"): Likewise. ("*return_32bit"): Likewise. * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Generate .far for 68HC11 too. (DWARF2_ADDR_SIZE): Use 4 so that addresses can * config/m68hc11/m68hc11.c (m68hc11_override_options): Accept -mlong-calls for 68HC11. * config/m68hc11/larith.asm (declare_near): New macro. (__premain, ___negsi2, ___one_cmplsi2, ___ashlsi3): Use it. (___ashrsi3, ___lshrsi3, ___lshrhi3, ___lshlhi3): Likewise. (___rotrhi3, ___rotlhi3, ___ashrhi3, ___ashrqi3): Likewise. (___lshlqi3, __divmodhi4, ___mulqi3, ___mulhi3): Likewise. (__mulhi32): Likewise. (ret): Update macro for 68HC11. (__far_trampoline): Implement for 68HC11. (__call_a16, __call_a32, __return_void, __return_16): New support routines for 68HC11 memory bank switching calling support. (__return_32): Likewise. From-SVN: r64825
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/config/m68hc11/larith.asm223
-rw-r--r--gcc/config/m68hc11/m68hc11.c1
-rw-r--r--gcc/config/m68hc11/m68hc11.h6
-rw-r--r--gcc/config/m68hc11/m68hc11.md64
-rw-r--r--gcc/config/m68hc11/t-m68hc11-gas6
6 files changed, 245 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cb19818..2dca24b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+2003-03-24 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and
+ _return_far
+ (MULTILIB_OPTIONS): Don't multilib on -mlong-calls.
+ (MULTILIB_EXCEPTIONS): Likewise.
+ * config/m68hc11/m68hc11.md ("call"): Support far calls for 68HC11
+ by calling some board support routine.
+ ("call_value"): Likewise.
+ ("*return_void"): Likewise for return.
+ ("*return_16bit"): Likewise.
+ ("*return_32bit"): Likewise.
+ * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Generate .far
+ for 68HC11 too.
+ (DWARF2_ADDR_SIZE): Use 4 so that addresses can
+ * config/m68hc11/m68hc11.c (m68hc11_override_options): Accept
+ -mlong-calls for 68HC11.
+ * config/m68hc11/larith.asm (declare_near): New macro.
+ (__premain, ___negsi2, ___one_cmplsi2, ___ashlsi3): Use it.
+ (___ashrsi3, ___lshrsi3, ___lshrhi3, ___lshlhi3): Likewise.
+ (___rotrhi3, ___rotlhi3, ___ashrhi3, ___ashrqi3): Likewise.
+ (___lshlqi3, __divmodhi4, ___mulqi3, ___mulhi3): Likewise.
+ (__mulhi32): Likewise.
+ (ret): Update macro for 68HC11.
+ (__far_trampoline): Implement for 68HC11.
+ (__call_a16, __call_a32, __return_void, __return_16): New support
+ routines for 68HC11 memory bank switching calling support.
+ (__return_32): Likewise.
+
2003-03-24 Neil Booth <neil@daikokuya.co.uk>
* toplev.c (independent_decode_option): Don't skip a 'Y' prefix.
diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm
index 0acf912..4d99fac 100644
--- a/gcc/config/m68hc11/larith.asm
+++ b/gcc/config/m68hc11/larith.asm
@@ -41,11 +41,22 @@ Boston, MA 02111-1307, USA. */
.mode mlong
#endif
-#if defined(__USE_RTC__) && defined(mc68hc12)
+ .macro declare_near name
+ .globl \name
+ .type \name,@function
+ .size \name,.Lend-\name
+\name:
+ .endm
+
+#if defined(__USE_RTC__)
# define ARG(N) N+1
.macro ret
+#if defined(mc68hc12)
rtc
+#else
+ jmp __return_32
+#endif
.endm
.macro declare name
@@ -181,10 +192,10 @@ REG(_.d32)
;; Specific initialization for 68hc11 before the main.
;; Nothing special for a generic routine; Just enable interrupts.
;;
- declare __premain
+ declare_near __premain
clra
tap ; Clear both I and X.
- ret
+ rts
#endif
#ifdef L__exit
@@ -299,7 +310,7 @@ L1:
puly ; Restore Y to return the DST
End:
xgdy
- rts
+ ret
#endif
#endif
@@ -349,7 +360,7 @@ L0:
pulx ; Restore X to return the DST
End:
xgdx
- rts
+ ret
#endif
#endif
@@ -438,10 +449,8 @@ End:
#endif
#ifdef L_negsi2
- .sect .text
- .globl ___negsi2
+ declare_near ___negsi2
-___negsi2:
comb
coma
xgdx
@@ -456,10 +465,8 @@ done:
#endif
#ifdef L_one_cmplsi2
- .sect .text
- .globl ___one_cmplsi2
+ declare_near ___one_cmplsi2
-___one_cmplsi2:
comb
coma
xgdx
@@ -470,10 +477,8 @@ ___one_cmplsi2:
#endif
#ifdef L_ashlsi3
- .sect .text
- .globl ___ashlsi3
+ declare_near ___ashlsi3
-___ashlsi3:
xgdy
clra
andb #0x1f
@@ -492,10 +497,8 @@ Return:
#endif
#ifdef L_ashrsi3
- .sect .text
- .globl ___ashrsi3
+ declare_near ___ashrsi3
-___ashrsi3:
xgdy
clra
andb #0x1f
@@ -515,10 +518,8 @@ Return:
#endif
#ifdef L_lshrsi3
- .sect .text
- .globl ___lshrsi3
+ declare_near ___lshrsi3
-___lshrsi3:
xgdy
clra
andb #0x1f
@@ -537,10 +538,8 @@ Return:
#endif
#ifdef L_lshrhi3
- .sect .text
- .globl ___lshrhi3
+ declare_near ___lshrhi3
-___lshrhi3:
cpx #16
bge Return_zero
cpx #0
@@ -558,10 +557,8 @@ Return_zero:
#endif
#ifdef L_lshlhi3
- .sect .text
- .globl ___lshlhi3
+ declare_near ___lshlhi3
-___lshlhi3:
cpx #16
bge Return_zero
cpx #0
@@ -579,8 +576,7 @@ Return_zero:
#endif
#ifdef L_rotrhi3
- .sect .text
- .globl ___rotrhi3
+ declare_near ___rotrhi3
___rotrhi3:
xgdx
@@ -599,8 +595,7 @@ Return:
#endif
#ifdef L_rotlhi3
- .sect .text
- .globl ___rotlhi3
+ declare_near ___rotlhi3
___rotlhi3:
xgdx
@@ -620,10 +615,8 @@ Return:
#endif
#ifdef L_ashrhi3
- .sect .text
- .globl ___ashrhi3
+ declare_near ___ashrhi3
-___ashrhi3:
cpx #16
bge Return_minus_1_or_zero
cpx #0
@@ -646,10 +639,8 @@ Return_zero:
#endif
#ifdef L_ashrqi3
- .sect .text
- .globl ___ashrqi3
+ declare_near ___ashrqi3
-___ashrqi3:
cmpa #8
bge Return_minus_1_or_zero
tsta
@@ -671,10 +662,8 @@ Return_zero:
#endif
#ifdef L_lshlqi3
- .sect .text
- .globl ___lshlqi3
+ declare_near ___lshlqi3
-___lshlqi3:
cmpa #8
bge Return_zero
tsta
@@ -694,8 +683,7 @@ Return_zero:
#ifndef mc68hc12
/* 68HC12 signed divisions are generated inline (idivs). */
- .sect .text
- .globl __divmodhi4
+ declare_near __divmodhi4
;
;; D = numerator
@@ -704,7 +692,6 @@ Return_zero:
;; Result: D = D / X
;; X = D % X
;;
-__divmodhi4:
tsta
bpl Numerator_pos
comb ; D = -D <=> D = (~D) + 1
@@ -762,8 +749,7 @@ Numerator_neg_denominator_pos:
#endif
#ifdef L_mulqi3
- .sect .text
- .globl __mulqi3
+ declare_near ___mulqi3
;
; short __mulqi3(signed char a, signed char b);
@@ -773,7 +759,6 @@ Numerator_neg_denominator_pos:
;
; returns the signed result of A * B in register D.
;
-__mulqi3:
tsta
bmi A_neg
tstb
@@ -800,8 +785,7 @@ AB_neg:
#endif
#ifdef L_mulhi3
- .sect .text
- .globl ___mulhi3
+ declare_near ___mulhi3
;
;
@@ -810,7 +794,6 @@ AB_neg:
; a = register D
; b = register X
;
-___mulhi3:
#ifdef mc68hc12
pshx ; Preserve X
exg x,y
@@ -846,24 +829,6 @@ ___mulhi3:
; ---
; 91 cycles
#else
- stx _.tmp ; (4/5)
- pshb ; (3)
- ldab _.tmp+1 ; (3/4)
- mul ; (10) B.high * A.low
- xgdx ; (3)
- pulb ; (4)
- stab _.tmp ; (3/4)
- mul ; (10) B.low * A.high
- abx ; (3)
- ldd _.tmp ; (4/5)
- mul ; (10) B.low * A.low
- stx _.tmp ; (4)
- adda _.tmp+1 ; (4/5)
- rts ; (5) 20/26 bytes
- ; ---
- ; 70/76 cycles
-
-#ifdef OLD_MUL
stx *_.tmp ; (4)
pshb ; (3)
ldab *_.tmp+1 ; (3)
@@ -884,7 +849,6 @@ ___mulhi3:
#endif
#endif
#endif
-#endif
#ifdef L_mulhi32
@@ -920,13 +884,13 @@ ___mulhi3:
; <A-low> 1,x
; <A-high> 0,x
;
- declare __mulhi32
+ declare_near __mulhi32
#ifdef mc68hc12
- ldy ARG(2),sp
+ ldy 2,sp
emul
exg x,y
- ret
+ rts
#else
pshx ; Room for temp value
pshb
@@ -1228,7 +1192,7 @@ dtors_done:
#ifdef L_far_tramp
#ifdef mc68hc12
- .sect .text
+ .sect .tramp,"ax",@progbits
.globl __far_trampoline
;; This is a trampoline used by the linker to invoke a function
@@ -1257,6 +1221,123 @@ __far_trampoline:
; (whose memory bank is mapped due to the
; call to the trampoline).
#endif
+
+#ifdef mc68hc11
+ .sect .tramp,"ax",@progbits
+ .globl __far_trampoline
+
+;; Trampoline generated by gcc for 68HC11:
+;;
+;; pshb
+;; ldab #%page(func)
+;; ldy #%addr(func)
+;; jmp __far_trampoline
+;;
+__far_trampoline:
+ psha ; (2) Save function parameter (high)
+ ;; <Read current page in A>
+ psha ; (2)
+ ;; <Set currenge page from B>
+ pshx ; (4)
+ tsx ; (3)
+ ldab 4,x ; (4) Restore function parameter (low)
+ ldaa 2,x ; (4) Get saved page number
+ staa 4,x ; (4) Save it below return PC
+ pulx ; (5)
+ pula ; (3)
+ pula ; (3) Restore function parameter (high)
+ jmp 0,y ; (4)
+#endif
+#endif
+
+#ifdef L_call_far
+#ifdef mc68hc11
+ .sect .tramp,"ax",@progbits
+ .globl __call_a16
+ .globl __call_a32
+;;
+;; The call methods are used for 68HC11 to support memory bank switching.
+;; Every far call is redirected to these call methods. Its purpose is to:
+;;
+;; 1/ Save the current page on the stack (1 byte to follow 68HC12 call frame)
+;; 2/ Install the new page
+;; 3/ Jump to the real function
+;;
+;; The page switching (get/save) is board dependent. The default provided
+;; here does nothing (just create the appropriate call frame).
+;;
+;; Call sequence (10 bytes, 13 cycles):
+;;
+;; ldx #page ; (3)
+;; ldy #func ; (4)
+;; jsr __call_a16 ; (6)
+;;
+;; Call trampoline (11 bytes, 19 cycles):
+;;
+__call_a16:
+ ;; xgdx ; (3)
+ ;; <Read current page in A> ; (3) ldaa _current_page
+ psha ; (2)
+ ;; <Set current page from B> ; (4) staa _current_page
+ ;; xgdx ; (3)
+ jmp 0,y ; (4)
+
+;;
+;; Call sequence (10 bytes, 14 cycles):
+;;
+;; pshb ; (2)
+;; ldab #page ; (2)
+;; ldy #func ; (4)
+;; jsr __call_a32 ; (6)
+;;
+;; Call trampoline (87 bytes, 57 cycles):
+;;
+__call_a32:
+ pshx ; (4)
+ psha ; (2)
+ ;; <Read current page in A> ; (3) ldaa _current_page
+ psha ; (2)
+ ;; <Set current page from B> ; (4) staa _current_page
+ tsx ; (3)
+ ldab 6,x ; (4) Restore function parameter
+ ldaa 5,x ; (4) Move PC return at good place
+ staa 6,x ; (4)
+ ldaa 4,x ; (4)
+ staa 5,x ; (4)
+ pula ; (3)
+ staa 4,x ; (4)
+ pula ; (3)
+ pulx ; (5)
+ jmp 0,y ; (4)
+#endif
+#endif
+
+#ifdef L_return_far
+#ifdef mc68hc11
+ .sect .tramp,"ax",@progbits
+ .globl __return_void
+ .globl __return_16
+ .globl __return_32
+
+__return_void:
+ ;; pulb
+ ;; <Set current page from B> (Board specific)
+ ;; rts
+__return_16:
+ ;; xgdx
+ ;; pulb
+ ;; <Set current page from B> (Board specific)
+ ;; xgdx
+ ;; rts
+__return_32:
+ ;; xgdy
+ ;; pulb
+ ;; <Set current page from B> (Board specific)
+ ;; xgdy
+ ;; rts
+ ins
+ rts
+#endif
#endif
.Lend:
;-----------------------------------------
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 1a0cd80..97d43d3 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -276,7 +276,6 @@ m68hc11_override_options ()
m68hc11_tmp_regs_class = D_REGS;
if (m68hc11_soft_reg_count == 0 && !TARGET_M6812)
m68hc11_soft_reg_count = "4";
- target_flags &= ~MASK_LONG_CALLS;
}
/* Configure for a 68hc12 processor. */
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 4ba1389..9f36afe 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1549,7 +1549,7 @@ do { \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
putc ('\n', FILE); \
\
- if (TARGET_M6812 && current_function_far) \
+ if (current_function_far) \
{ \
fprintf (FILE, "\t.far\t"); \
assemble_name (FILE, NAME); \
@@ -1629,6 +1629,10 @@ do { \
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+/* For the support of memory banks we need addresses that indicate
+ the page number. */
+#define DWARF2_ADDR_SIZE 4
+
/* The prefix for local labels. You should be able to define this as
an empty string, or any arbitrary string (such as ".", ".L%", etc)
without having to make any other changes to account for the specific
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index 3535a89..5acbc2e 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -1,5 +1,5 @@
;;- Machine description file for Motorola 68HC11 and 68HC12.
-;;- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;;- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
;;- Contributed by Stephane Carrez (stcarrez@nerim.fr)
;; This file is part of GNU CC.
@@ -6394,8 +6394,18 @@
{
if (m68hc11_is_far_symbol (operands[0]))
{
- output_asm_insn (\"call\\t%0\", operands);
- return \"\";
+ if (TARGET_M6812)
+ {
+ output_asm_insn (\"call\\t%0\", operands);
+ return \"\";
+ }
+ else
+ {
+ output_asm_insn (\"pshb\", operands);
+ output_asm_insn (\"ldab\\t#%%page(%0)\", operands);
+ output_asm_insn (\"ldy\\t#%%addr(%0)\", operands);
+ return \"jsr\\t__call_a32\";
+ }
}
if (m68hc11_is_trap_symbol (operands[0]))
return \"swi\";
@@ -6419,8 +6429,18 @@
{
if (m68hc11_is_far_symbol (operands[1]))
{
- output_asm_insn (\"call\\t%1\", operands);
- return \"\";
+ if (TARGET_M6812)
+ {
+ output_asm_insn (\"call\\t%1\", operands);
+ return \"\";
+ }
+ else
+ {
+ output_asm_insn (\"pshb\", operands);
+ output_asm_insn (\"ldab\\t#%%page(%1)\", operands);
+ output_asm_insn (\"ldy\\t#%%addr(%1)\", operands);
+ return \"jsr\\t__call_a32\";
+ }
}
if (m68hc11_is_trap_symbol (operands[1]))
return \"swi\";
@@ -6539,7 +6559,25 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return current_function_far ? \"rtc\" : \"rts\";
+ else if (!current_function_far)
+ return \"rts\";
+ else if (TARGET_M6812)
+ return \"rtc\";
+ else
+ {
+ int ret_size = 0;
+
+ if (current_function_return_rtx)
+ ret_size = GET_MODE_SIZE (GET_MODE (current_function_return_rtx));
+
+ if (ret_size == 0)
+ return \"jmp\\t__return_void\";
+ if (ret_size <= 2)
+ return \"jmp\\t__return_16\";
+ if (ret_size <= 4)
+ return \"jmp\\t__return_32\";
+ return \"jmp\\t__return_16\";
+ }
}")
(define_insn "*return_16bit"
@@ -6556,7 +6594,12 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return current_function_far ? \"rtc\" : \"rts\";
+ else if (!current_function_far)
+ return \"rts\";
+ else if (TARGET_M6812)
+ return \"rtc\";
+ else
+ return \"jmp\\t__return_16\";
}")
(define_insn "*return_32bit"
@@ -6573,7 +6616,12 @@
return \"\";
if (current_function_interrupt || current_function_trap)
return \"rti\";
- return current_function_far ? \"rtc\" : \"rts\";
+ else if (!current_function_far)
+ return \"rts\";
+ else if (TARGET_M6812)
+ return \"rtc\";
+ else
+ return \"jmp\\t__return_32\";
}")
(define_insn "indirect_jump"
diff --git a/gcc/config/m68hc11/t-m68hc11-gas b/gcc/config/m68hc11/t-m68hc11-gas
index b5404cc..3415348 100644
--- a/gcc/config/m68hc11/t-m68hc11-gas
+++ b/gcc/config/m68hc11/t-m68hc11-gas
@@ -25,7 +25,7 @@ LIB1ASMFUNCS = _mulsi3 \
_premain __exit _abort _cleanup \
_adddi3 _subdi3 _notdi2 _rotlhi3 _rotrhi3 \
_ashrhi3 _lshrhi3 _lshlhi3 _ashrqi3 _lshlqi3 _map_data _init_bss \
- _ctor _dtor __far_trampoline
+ _ctor _dtor _far_tramp _call_far _return_far
TARGET_LIBGCC2_CFLAGS = -DUSE_GAS -DIN_GCC
@@ -37,10 +37,10 @@ LIB2FUNCS_EXTRA = $(srcdir)/config/udivmodsi4.c \
LIBGCC2_DEBUG_CFLAGS =-g
LIBGCC2_CFLAGS = -Os -mrelax $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
-MULTILIB_OPTIONS = m68hc11/m68hc12 mshort fshort-double mlong-calls
+MULTILIB_OPTIONS = m68hc11/m68hc12 mshort fshort-double
MULTILIB_DIRNAMES =
MULTILIB_MATCHES = m68hc11=m6811 m68hc12=m6812
-MULTILIB_EXCEPTIONS = -mnoshort -mno68hc11 -mnolong-calls
+MULTILIB_EXCEPTIONS = -mnoshort -mno68hc11
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib