diff options
author | Stephane Carrez <stcarrez@nerim.fr> | 2003-03-24 23:26:05 +0100 |
---|---|---|
committer | Stephane Carrez <ciceron@gcc.gnu.org> | 2003-03-24 23:26:05 +0100 |
commit | dbcedbc4b7380379398d655d332176c84b13f4f9 (patch) | |
tree | 0fb3f4bd3ccb2feadfa864ab69fa1909f3ae2c12 | |
parent | eea5120f8227183584f4041629cd7a69055ba467 (diff) | |
download | gcc-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/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/config/m68hc11/larith.asm | 223 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.c | 1 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.h | 6 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.md | 64 | ||||
-rw-r--r-- | gcc/config/m68hc11/t-m68hc11-gas | 6 |
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 |