This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Support far calls on 68HC11


Hi!

I committed this patch on 3_3 and mainline to:

  - support memory bank switching for 68HC11 (ie, 68HC11 call/rtc calling convention)
    This is done by calling a board support routine that must save the current page
    number on the stack, install the new page number and jump to the real routine
    (as the 'call' insn does on HC12)
    For the return, the board support routine must pop the page number, restore it
    and return to the caller.

  - fix debugging problems for programs in memory bank windows (we now need 4-bytes
    dwarf addresses)

- avoid generation of multilib for -mlong-calls

Stephane

2003-03-24 Stephane Carrez <stcarrez at nerim dot 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.
Index: config/m68hc11/larith.asm
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/larith.asm,v
retrieving revision 1.11
diff -u -p -r1.11 larith.asm
--- config/m68hc11/larith.asm	2 Mar 2003 20:04:26 -0000	1.11
+++ config/m68hc11/larith.asm	24 Mar 2003 22:24:06 -0000
@@ -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
@@ -1256,6 +1220,123 @@ __far_trampoline:
 				; and can jump to the far handler
 				; (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: config/m68hc11/m68hc11.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.c,v
retrieving revision 1.70
diff -u -p -r1.70 m68hc11.c
--- config/m68hc11/m68hc11.c	21 Mar 2003 23:25:20 -0000	1.70
+++ config/m68hc11/m68hc11.c	24 Mar 2003 22:24:12 -0000
@@ -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: config/m68hc11/m68hc11.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.h,v
retrieving revision 1.68
diff -u -p -r1.68 m68hc11.h
--- config/m68hc11/m68hc11.h	21 Mar 2003 23:25:20 -0000	1.68
+++ config/m68hc11/m68hc11.h	24 Mar 2003 22:24:12 -0000
@@ -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);			\
@@ -1628,6 +1628,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)
Index: config/m68hc11/m68hc11.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.md,v
retrieving revision 1.49
diff -u -p -r1.49 m68hc11.md
--- config/m68hc11/m68hc11.md	21 Mar 2003 23:35:11 -0000	1.49
+++ config/m68hc11/m68hc11.md	24 Mar 2003 22:24:16 -0000
@@ -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 at nerim dot 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"
Index: config/m68hc11/t-m68hc11-gas
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/t-m68hc11-gas,v
retrieving revision 1.8
diff -u -p -r1.8 t-m68hc11-gas
--- config/m68hc11/t-m68hc11-gas	2 Mar 2003 20:04:27 -0000	1.8
+++ config/m68hc11/t-m68hc11-gas	24 Mar 2003 22:24:16 -0000
@@ -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/udivm
 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]