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] m68k: ISAC corrections (Part 3)


Hi,

Attached is a patch to correct the ISAC support.

ISAC is not backward compatible with ISAB.  Specifically, the long
branch instruction is missing in ISAC even though it is available in
ISAB.  (ColdFire's instruction set manual says so.  Nathan has
confirmed with Freescale as well.)  However, ISAC is compatible with
ISAA, and it has hardware division instructions.  To reflect all this,
this patch updates FL_FOR_isa_c.

The lack of the long branch instruction means that we cannot do a
symbolic jump even though we can do a symbolic call, which in turn
means that we cannot do a sibcall.

Without this patch, a sibcall to a symbolic address is said to be
available if m68k_symbolic_call is non-null.  With ISAC, the condition
is no longer correct.  We need to say that a sibcall to a symbolic
address is available if m68k_symbolic_jump is non-null.  This patch
teaches sibcall_operand to check the new predicate
const_sibcall_operand, which looks at m68k_symbolic_jump, not
m68k_symbolic_call.

Tested by building m68k-elf.  OK to apply?

Kazu Hirata

2007-06-15  Nathan Sidwell  <nathan@codesourcery.com>

	* config/m68k/predicates.md (const_call_operand): Adjust comment.
	(const_sibcall_operand): New.
	(sibcall_operand): Use it.
	* config/m68k/m68k-devices.def: Add 54450..54455.
	* config/m68k/m68k.c (FL_FOR_isa_c): Not ISA_B compatible.
	(m68k_isas): ISAC does not imply FPU or EMAC.
	(override_options): Add ISA_C logic for symbolic jump & call.

Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	(revision 125739)
+++ gcc/config/m68k/m68k.c	(working copy)
@@ -233,7 +233,8 @@ struct gcc_target targetm = TARGET_INITI
 #define FL_FOR_isa_aplus (FL_FOR_isa_a | FL_ISA_APLUS | FL_CF_USP)
 /* Note ISA_B doesn't necessarily include USP (user stack pointer) support.  */
 #define FL_FOR_isa_b     (FL_FOR_isa_a | FL_ISA_B | FL_CF_HWDIV)
-#define FL_FOR_isa_c     (FL_FOR_isa_b | FL_ISA_C | FL_CF_USP)
+/* ISA_C is not upwardly compatible with ISA_B.  */
+#define FL_FOR_isa_c     (FL_FOR_isa_a | FL_ISA_C | FL_CF_HWDIV | FL_CF_USP)
 
 enum m68k_isa
 {
@@ -565,20 +566,27 @@ override_options (void)
   else if (TARGET_ID_SHARED_LIBRARY)
     /* All addresses must be loaded from the GOT.  */
     ;
-  else if (TARGET_68020 || TARGET_ISAB)
+  else if (TARGET_68020 || TARGET_ISAB || TARGET_ISAC)
     {
       if (TARGET_PCREL)
+	m68k_symbolic_call = "bsr.l %c0";
+      else
 	{
-	  m68k_symbolic_call = "bsr.l %c0";
-	  m68k_symbolic_jump = "bra.l %c0";
+#if defined(USE_GAS)
+	  m68k_symbolic_call = "bsr.l %p0";
+#else
+	  m68k_symbolic_call = "bsr %p0";
+#endif
 	}
+      if (TARGET_ISAC)
+	/* No unconditional long branch */;
+      else if (TARGET_PCREL)
+	m68k_symbolic_jump = "bra.l %c0";
       else
 	{
 #if defined(USE_GAS)
-	  m68k_symbolic_call = "bsr.l %p0";
 	  m68k_symbolic_jump = "bra.l %p0";
 #else
-	  m68k_symbolic_call = "bsr %p0";
 	  m68k_symbolic_jump = "bra %p0";
 #endif
 	}
Index: gcc/config/m68k/predicates.md
===================================================================
--- gcc/config/m68k/predicates.md	(revision 125739)
+++ gcc/config/m68k/predicates.md	(working copy)
@@ -159,7 +159,7 @@ (define_predicate "symbolic_operand"
     }
 })
 
-;; A constant that can be used the address in a call or sibcall insn.
+;; A constant that can be used the address in a call insn
 (define_predicate "const_call_operand"
   (ior (match_operand 0 "const_int_operand")
        (and (match_test "m68k_symbolic_call != NULL")
@@ -170,9 +170,15 @@ (define_predicate "call_operand"
   (ior (match_operand 0 "const_call_operand")
        (match_operand 0 "register_operand")))
 
+;; A constant that can be used the address in a sibcall insn
+(define_predicate "const_sibcall_operand"
+  (ior (match_operand 0 "const_int_operand")
+       (and (match_test "m68k_symbolic_jump != NULL")
+	    (match_operand 0 "symbolic_operand"))))
+
 ;; An operand that can be used as the address in a sibcall insn.
 (define_predicate "sibcall_operand"
-  (ior (match_operand 0 "const_call_operand")
+  (ior (match_operand 0 "const_sibcall_operand")
        (and (match_code "reg")
 	    (match_test "REGNO (op) == STATIC_CHAIN_REGNUM"))))
 


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