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] Fix extendsidi pattern to handle ColdFire


Hello,

The attached patch fixes problem in extendsidi2_mem pattern that allows it to output instruction that does not take into account ColdFire addressing restrictions. Specifically, the last alternative allows offset addressing for both operands while ColdFire can handle at most one offset in an instruction.

To fix the problem patch cleans up extendsidi2 and extendsidi2_mem patterns merging them into one and adds a ColdFire-specific alternative to the result.

Tested on ColdFire bare-metal. OK for trunk?

--
MaximK
CodeSourcery
2008-11-19  Maxim Kuvyrkov  <maxim@codesourcery.com>

	* config/m68k/m68k.md (ok_for_coldfire, enabled): New attributes.
	(extendsidi2, extendsidi2_mem): Merge, clean up.  Disable unsupported
	alternative for ColdFire, add new alternative that ColdFire can handle.

2008-11-19  Maxim Kuvyrkov  <maxim@codesourcery.com>

	* gcc.c-torture/compile/20080929-1.c: New.
Index: testsuite/gcc.c-torture/compile/20080929-1.c
===================================================================
*** testsuite/gcc.c-torture/compile/20080929-1.c	(revision 0)
--- testsuite/gcc.c-torture/compile/20080929-1.c	(revision 0)
***************
*** 0,-1 ****
--- 1,39 ----
+ struct option {
+   const char *name;
+   int has_arg;
+   int *flag;
+   int val;
+ };
+ enum {
+   UBI_DYNAMIC_VOLUME = 3,  UBI_STATIC_VOLUME = 4, };
+ typedef void * libubi_t;
+ struct ubi_dev_info {
+   int leb_size;
+ };
+ struct args {
+   int vol_id;
+   int vol_type;
+   long long bytes;
+   int lebs;
+   int alignment;
+   const char *node;
+   int maxavs;
+   int devn;
+ };
+ static struct args args = {
+   .vol_type = UBI_DYNAMIC_VOLUME,  .bytes = -1,  .lebs = -1,  .alignment = 1,  .vol_id = (-1),  .devn = -1, };
+ extern libubi_t libubi_open (int);
+ extern int ubi_get_dev_info (libubi_t, const char *, struct ubi_dev_info *);
+ int main(int argc, char * const argv[]) {
+   int err;
+   libubi_t libubi;
+   struct ubi_dev_info dev_info;
+   libubi = libubi_open(1);
+   if (!libubi)
+     return 0;
+   err = ubi_get_dev_info(libubi, args.node, &dev_info);
+   if (args.maxavs) {
+     args.bytes = dev_info.leb_size;
+   }
+   return 0;
+ }
Index: config/m68k/m68k.md
===================================================================
*** config/m68k/m68k.md	(revision 141999)
--- config/m68k/m68k.md	(working copy)
***************
*** 244,249 ****
--- 244,258 ----
  (define_attr "size" "1,2,3"
    (symbol_ref "m68k_sched_attr_size (insn)"))
  
+ ;; Alternative is OK for ColdFire.
+ (define_attr "ok_for_coldfire" "yes,no" "yes")
+ 
+ ;; Define 'enabled' attribute.
+ (define_attr "enabled" ""
+   (cond [(and (neq (symbol_ref "TARGET_COLDFIRE") (const_int 0))
+ 	      (eq_attr "ok_for_coldfire" "no"))
+ 	 (const_int 0)]
+ 	(const_int 1)))
  
  ;; Mode macros for floating point operations.
  ;; Valid floating point modes
***************
*** 1694,1725 ****
  })
  
  (define_insn "extendsidi2"
!   [(set (match_operand:DI 0 "register_operand" "=d")
! 	(sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm")))]
    ""
  {
    CC_STATUS_INIT;
-   if (TARGET_68020 || TARGET_COLDFIRE)
-     return "move%.l %1,%R0\;smi %0\;extb%.l %0";
-   else
-     return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
- })
  
! (define_insn "*extendsidi2_mem"
!   [(set (match_operand:DI 0 "memory_operand" "=o,<")
! 	(sign_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm")))
!    (clobber (match_scratch:SI 2 "=d,d"))]
!    ""
! {
!   CC_STATUS_INIT;
    operands[3] = adjust_address (operands[0], SImode,
! 				which_alternative == 0 ? 4 : 0);
    operands[0] = adjust_address (operands[0], SImode, 0);
    if (TARGET_68020 || TARGET_COLDFIRE)
      return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
    else
      return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
! })
  
  ;; Special case when one can avoid register clobbering, copy and test
  ;; Maybe there is a way to make that the general case, by forcing the
--- 1703,1739 ----
  })
  
  (define_insn "extendsidi2"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o,o,<")
! 	(sign_extend:DI
! 	 (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,r<Q>,rm")))
!    (clobber (match_scratch:SI 2 "=X,d,d,d"))
! ;; Operand 3 is used during output as a temp.
!    (clobber (match_scratch:SI 3 "=X,X,X,X"))]
    ""
  {
    CC_STATUS_INIT;
  
!   if (which_alternative == 0)
!     /* Handle alternative 0.  */
!     {
!       if (TARGET_68020 || TARGET_COLDFIRE)
!         return "move%.l %1,%R0\;smi %0\;extb%.l %0";
!       else
!         return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
!     }
! 
!   /* Handle alternatives 1, 2 and 3.  We don't need to adjust address by 4
!      in alternative 3 because autodecrement will do that for us.  */
    operands[3] = adjust_address (operands[0], SImode,
! 				which_alternative == 3 ? 0 : 4);
    operands[0] = adjust_address (operands[0], SImode, 0);
+ 
    if (TARGET_68020 || TARGET_COLDFIRE)
      return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
    else
      return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
! }
!   [(set_attr "ok_for_coldfire" "yes,no,yes,yes")])
  
  ;; Special case when one can avoid register clobbering, copy and test
  ;; Maybe there is a way to make that the general case, by forcing the

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