]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and _return_far
authorStephane Carrez <stcarrez@nerim.fr>
Mon, 24 Mar 2003 22:26:05 +0000 (23:26 +0100)
committerStephane Carrez <ciceron@gcc.gnu.org>
Mon, 24 Mar 2003 22:26:05 +0000 (23:26 +0100)
* 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

gcc/ChangeLog
gcc/config/m68hc11/larith.asm
gcc/config/m68hc11/m68hc11.c
gcc/config/m68hc11/m68hc11.h
gcc/config/m68hc11/m68hc11.md
gcc/config/m68hc11/t-m68hc11-gas

index cb19818353f4f46ec7510c0d2ade158b9ac55805..2dca24bca0d95ca12a0e185061d8f55f7663c241 100644 (file)
@@ -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.
index 0acf91228597655d5cf82aa72f4c472e4caddc62..4d99fac2d259af8409cdd41bbdd72ab78976a75e 100644 (file)
@@ -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:
 ;-----------------------------------------
index 1a0cd80aed0f67b5063881d54a03fe13d4dcce41..97d43d304b677ac80bf9f0448b61fa42ec45b2bc 100644 (file)
@@ -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.  */
index 4ba138908b236ded5600f21929b038fc457b6446..9f36afe5f0e87b5272b3ebc7b4272edc878d67b1 100644 (file)
@@ -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
index 3535a89084dc9b330ae34df796697f5fd9fe906a..5acbc2ea030bbd1c61218912243605ee96caf6e0 100644 (file)
@@ -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.
     {
       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\";
     {
       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\";
     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"
     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"
     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"
index b5404cc84797347d76f8f0c66c9a93e1fc25a679..3415348944168bef7c6b57a4d86f78510ac339b0 100644 (file)
@@ -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