This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][M68K] Fix extendsidi pattern to handle ColdFire
- From: Maxim Kuvyrkov <maxim at codesourcery dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: Andreas Schwab <schwab at suse dot de>
- Date: Wed, 19 Nov 2008 15:34:11 +0100
- Subject: [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