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]

Some mcore fixes


No-one seems to have objected in principle to:

   http://gcc.gnu.org/ml/gcc/2003-08/msg01412.html

so I thought I'd get the patch ready for submission.  This first
part deals with mcore fallout.

The regressions I mentioned were due to movdi not handling certain
constants during reload.  They are fixed with the movdi hunk below.

I noticed there were a few existing failures due to other
move-related issues:

  - When the source is a non-inlineable constant, movhi and movqi
    use an SImode temporary.  As the final step, they move the lowpart
    of that temporary into operands[0].

    A lot of little-endian failures were due to this code using
    gen_rtx (SUBREG, ..., 0) rather than an endian-aware function
    like gen_lowpart.  

  - The move patterns take elaborate countermeasures if reload tries
    to move a constant into r15.  But these measures only work for
    CONST_INTs, not for symbolic constants.  It seems simpler to
    admit that certain constants can't be reloaded directly into
    r15 and define SECONDARY_RELOAD_CLASS accordingly.

    (While this doesn't fix an observed failure after the reload
    change linked above, it could certainly trigger in principle.)

Also, the move patterns can handle r15 <- P-type constants just fine.
There doesn't seem any need to deal with them differently from other
reg <- P moves.

Patch tested on mcore-elf {-mlittle-endian,-mbig-endian} (without the
reload changedlinked above).  Number of check-gcc failures goes down
from 615 to 444.  OK to install?

Richard


	* config/mcore/mcore-protos.h (mcore_r15_operand_p): Declare.
	(mcore_secondary_reload_class): Declare.
	(mcore_output_inline_const_forced): Remove.
	* config/mcore/mcore.md (movsi): Remove the code that forced
	non-inlineable constants into a register if the target was r15
	or the stack pointer.  Remove constant restrictions from the main
	define_insn.  Remove r <- I, r <- M and r <- N alternatives in favor
	of an r <- P alternative.  Remove fallback define_insn for reload.
	(movhi, movqi): Use gen_lowpart rather than gen_SUBREG.  Remove reload
	define_insn.  Use mcore_output_move in the remaining define_insn.
	Adjust condition and constraints in the way as for movsi.
	(movdi): Always split unacceptable constants into two.  Use
	simplify_gen_subreg instead of operand_subword{,_force}.
	* config/mcore/mcore.c (mcore_output_inline_const_forced): Remove.
	(mcore_output_move): Support HImode and QImode moves as well.
	(mcore_m15_operand_p): New function.
	(mcore_reload_class): Use it to detect cases where LRW_REGS are better.
	(mcore_secondary_reload_class): New function.
	* config/mcore/mcore.h (SECONDARY_RELOAD_CLASS): Redefine in
	terms of mcore_secondary_reload_class.

Index: config/mcore/mcore-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore-protos.h,v
retrieving revision 1.12
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.12 mcore-protos.h
*** config/mcore/mcore-protos.h	14 May 2003 07:29:50 -0000	1.12
--- config/mcore/mcore-protos.h	1 Sep 2003 09:29:46 -0000
*************** extern void         mcore_print_operand_
*** 65,70 ****
--- 64,71 ----
  extern void         mcore_print_operand          	PARAMS ((FILE *, rtx, int));
  extern rtx          mcore_gen_compare_reg        	PARAMS ((RTX_CODE));
  extern int          mcore_symbolic_address_p     	PARAMS ((rtx));
+ extern bool         mcore_r15_operand_p			PARAMS ((rtx));
+ extern enum reg_class mcore_secondary_reload_class	PARAMS ((enum reg_class, enum machine_mode, rtx));
  extern enum reg_class mcore_reload_class 		PARAMS ((rtx, enum reg_class));
  extern int          mcore_is_same_reg            	PARAMS ((rtx, rtx));
  extern int          mcore_arith_S_operand         	PARAMS ((rtx));
*************** extern int          mcore_arith_S_operan
*** 72,78 ****
  #ifdef HAVE_MACHINE_MODES
  extern const char * mcore_output_move          		PARAMS ((rtx, rtx *, enum machine_mode));
  extern const char * mcore_output_movedouble    		PARAMS ((rtx *, enum machine_mode));
- extern const char * mcore_output_inline_const_forced	PARAMS ((rtx, rtx *, enum machine_mode));
  extern int          mcore_arith_reg_operand       	PARAMS ((rtx, enum machine_mode));
  extern int          mcore_general_movsrc_operand  	PARAMS ((rtx, enum machine_mode));
  extern int          mcore_general_movdst_operand  	PARAMS ((rtx, enum machine_mode));
--- 73,78 ----
Index: config/mcore/mcore.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.md,v
retrieving revision 1.11
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.11 mcore.md
*** config/mcore/mcore.md	3 Jul 2003 12:34:07 -0000	1.11
--- config/mcore/mcore.md	1 Sep 2003 09:29:47 -0000
*************** (define_expand "movsi"
*** 1226,1326 ****
  {
    if (GET_CODE (operands[0]) == MEM)
      operands[1] = force_reg (SImode, operands[1]);
-   else if (CONSTANT_P (operands[1])
- 	   && (GET_CODE (operands[1]) != CONST_INT
- 	       || (   ! CONST_OK_FOR_I (INTVAL (operands[1]))
- 		   && ! CONST_OK_FOR_M (INTVAL (operands[1]))
- 		   && ! CONST_OK_FOR_N (INTVAL (operands[1]))
-                    && (! TARGET_HARDLIT ||
-                        ! mcore_const_ok_for_inline (INTVAL (operands[1])))))
- 	   && ! reload_completed
- 	   && ! reload_in_progress
- 	   && GET_CODE (operands[0]) == REG
- 	   && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
- 	   && (REGNO (operands[0]) == STACK_POINTER_REGNUM
- 	       || REGNO (operands[0]) == LK_REG))
-     operands[1] = force_reg (SImode, operands[1]);
  }")
  
- ;;; Must put a/i before r/r so that it will be preferred when the dest is
- ;;; a hard register.  Must put a/R before r/m.
- ;;; DO WE NEED a/i ANYMORE?
- 
  (define_insn ""
!   [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,r,a,r,r,a,r,m")
! 	(match_operand:SI 1 "mcore_general_movsrc_operand"  "I,M,N,i,r,c,R,m,r"))]
    "(register_operand (operands[0], SImode)
!        || register_operand (operands[1], SImode))
!    && ! (CONSTANT_P (operands[1])
!          && (GET_CODE (operands[1]) != CONST_INT
! 	     || (   ! CONST_OK_FOR_I (INTVAL (operands[1]))
!                  && ! CONST_OK_FOR_M (INTVAL (operands[1]))
!                  && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
! 	 && GET_CODE (operands[0]) == REG
! 	 && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
!          && (REGNO (operands[0]) == STACK_POINTER_REGNUM
! 	     || REGNO (operands[0]) == LK_REG))"
    "* return mcore_output_move (insn, operands, SImode);"
!   [(set_attr "type" "move,move,move,move,move,move,load,load,store")])
! 
! ;; This is to work around a bug in reload.
! (define_insn ""
!   [(set (match_operand:SI 0 "register_operand" "=r")
! 	(match_operand:SI 1 "immediate_operand" "i"))]
!   "((reload_in_progress || reload_completed)
!    && CONSTANT_P (operands[1])
!    && GET_CODE (operands[1]) == CONST_INT
!    && ! CONST_OK_FOR_I (INTVAL (operands[1]))
!    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
!    && ! CONST_OK_FOR_N (INTVAL (operands[1]))
!    && GET_CODE (operands[0]) == REG
!    && REGNO (operands[0]) == LK_REG)"
!   "* return mcore_output_inline_const_forced (insn, operands, SImode);"
!   [(set_attr "type" "load")])
  
- ;; (define_expand "reload_insi"
- ;;   [(parallel [(match_operand:SI 0 "register_operand" "=r")
- ;; 	      (match_operand:SI 1 "general_operand"  "")
- ;; 	      (match_operand:DI 2 "register_operand" "=&r")])]
- ;;   ""
- ;;   "
- ;;   {
- ;;     if (CONSTANT_P (operands[1])
- ;;        && GET_CODE (operands[1]) == CONST_INT
- ;;        && ! CONST_OK_FOR_I (INTVAL (operands[1]))
- ;;        && ! CONST_OK_FOR_M (INTVAL (operands[1]))
- ;;        && ! CONST_OK_FOR_N (INTVAL (operands[1]))
- ;;        && GET_CODE (operands[0]) == REG
- ;;        && (REGNO (operands[0]) == STACK_POINTER_REGNUM
- ;;           || REGNO (operands[0]) == LK_REG))
- ;;       {
- ;;         rtx tmp;
- ;; 
- ;; 	if (   REGNO (operands[2]) == REGNO (operands[0])
- ;;             || REGNO (operands[2]) == STACK_POINTER_REGNUM
- ;; 	    || REGNO (operands[2]) == LK_REG)
- ;;           tmp = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
- ;; 	else
- ;;           tmp = gen_rtx_REG (SImode, REGNO (operands[2]));
- ;; 	
- ;;         emit_insn (gen_movsi (tmp, operands[1]));
- ;;         emit_insn (gen_movsi (operands[0], tmp));
- ;;         DONE;
- ;;       }
- ;;     emit_insn (gen_movsi (operands[0], operands[1]));
- ;;     DONE;
- ;;   }"
- ;; )
- 			       
- 	    
- 			       
  ;;
  ;; HImode
  ;;
  
- ;;; ??? This isn't guaranteed to work.  It should be more like the SImode
- ;;; patterns.
- 
  (define_expand "movhi"
    [(set (match_operand:HI 0 "general_operand" "")
  	(match_operand:HI 1 "general_operand"  ""))]
--- 1226,1245 ----
  {
    if (GET_CODE (operands[0]) == MEM)
      operands[1] = force_reg (SImode, operands[1]);
  }")
  
  (define_insn ""
!   [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,a,r,a,r,m")
! 	(match_operand:SI 1 "mcore_general_movsrc_operand"  "r,P,i,c,R,m,r"))]
    "(register_operand (operands[0], SImode)
!     || register_operand (operands[1], SImode))"
    "* return mcore_output_move (insn, operands, SImode);"
!   [(set_attr "type" "move,move,move,move,load,load,store")])
  
  ;;
  ;; HImode
  ;;
  
  (define_expand "movhi"
    [(set (match_operand:HI 0 "general_operand" "")
  	(match_operand:HI 1 "general_operand"  ""))]
*************** (define_expand "movhi"
*** 1338,1410 ****
      {
        rtx reg = gen_reg_rtx (SImode);
        emit_insn (gen_movsi (reg, operands[1]));
!       operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
      }
  }")
    
  (define_insn ""
!   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m")
! 	(match_operand:HI 1 "mcore_general_movsrc_operand"  "r,I,M,N,c,m,r"))]
    "(register_operand (operands[0], HImode)
!        || register_operand (operands[1], HImode))
!    && (GET_CODE (operands[1]) != CONST_INT
!        || CONST_OK_FOR_M (INTVAL (operands[1]))
!        || CONST_OK_FOR_N (INTVAL (operands[1]))
!        || CONST_OK_FOR_I (INTVAL (operands[1])))"
!   "@
! 	mov	%0,%1
! 	movi	%0,%1
! 	bgeni	%0,%P1
! 	bmaski	%0,%N1
! 	mvc	%0
! 	ld.h	%0,%1
! 	st.h	%1,%0"
!   [(set_attr "type" "move,move,move,move,move,load,store")])
! 
! ;; Like movhi, but the const_int source can't be synthesized in
! ;; a single-instruction.  Fall back to the same things that 
! ;; are done for movsi in such cases.  Presumes that we can
! ;; modify any parts of the register that we wish.
! 
! (define_insn ""
!   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a")
! 	(match_operand:HI 1 "const_int_operand"  "P,i"))]
!   "GET_CODE (operands[1]) == CONST_INT
!     && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 65536"
!   "*
! {
!   if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
!       && !mcore_const_ok_for_inline (INTVAL (operands[1])))
!     {
!       /* mcore_output_move would generate lrw r15 -- a forbidden combo */
!       return mcore_output_inline_const_forced (insn, operands, SImode);
!     }
!   else
!     return mcore_output_move (insn, operands, SImode);
! }"
!   [(set_attr "type" "move")])
! 
! 
! ;; if we're still looking around for things to use, here's a last
! ;; ditch effort that just calls the move. We only let this happen
! ;; if we're in the reload pass.
! ;;
! (define_insn ""
!   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a")
! 	(match_operand:HI 1 "const_int_operand"  "P,i"))]
!   "reload_in_progress || reload_completed"
!   "*
! {
!   if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
!       && !mcore_const_ok_for_inline (INTVAL (operands[1])))
!     {
!       /* mcore_output_move would generate lrw r15 -- a forbidden combo */
!       return mcore_output_inline_const_forced (insn, operands, SImode);
!     }
!   else
!     return mcore_output_move (insn, operands, HImode);
! }"
!   [(set_attr "type" "move")])
  
  ;;
  ;; QImode
--- 1257,1273 ----
      {
        rtx reg = gen_reg_rtx (SImode);
        emit_insn (gen_movsi (reg, operands[1]));
!       operands[1] = gen_lowpart (HImode, reg);
      }
  }")
    
  (define_insn ""
!   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
! 	(match_operand:HI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
    "(register_operand (operands[0], HImode)
!     || register_operand (operands[1], HImode))"
!   "* return mcore_output_move (insn, operands, HImode);"
!   [(set_attr "type" "move,move,move,move,load,store")])
  
  ;;
  ;; QImode
*************** (define_expand "movqi"
*** 1427,1493 ****
      {
        rtx reg = gen_reg_rtx (SImode);
        emit_insn (gen_movsi (reg, operands[1]));
!       operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
      }
  }")
    
  (define_insn ""
!   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m")
! 	(match_operand:QI 1 "mcore_general_movsrc_operand"  "r,I,M,N,c,m,r"))]
    "(register_operand (operands[0], QImode)
!        || register_operand (operands[1], QImode))
!    && (GET_CODE (operands[1]) != CONST_INT
!        || CONST_OK_FOR_M (INTVAL (operands[1]))
!        || CONST_OK_FOR_N (INTVAL (operands[1]))
!        || CONST_OK_FOR_I (INTVAL (operands[1])))"
!   "@
! 	mov	%0,%1
! 	movi	%0,%1
! 	bgeni	%0,%P1
! 	bmaski	%0,%N1
! 	mvc	%0
! 	ld.b	%0,%1
! 	st.b	%1,%0" 
!    [(set_attr "type" "move,move,move,move,move,load,store")])
  
- ;; cover the case where the constant is 128..255; this isn't handled
- ;; in the above case. We could if we wanted to mess with adding a 
- ;; new constraint class like M,N,I.
- (define_insn ""
-   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r")
- 	(match_operand:QI 1 "const_int_operand"  ""))]
-   "GET_CODE (operands[1]) == CONST_INT
-     && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 256"
-   "*
- {
-    /* have a constant in range 128..255; have to do 2 insns; we can
-     * do this with a movi followed by a bseti
-     */
-    operands[2] = GEN_INT (INTVAL (operands[1]) & 0x7f);
-    return \"movi\\t%0,%2\;bseti\\t%0,7\";
- }"
-   [(set_attr "type" "move")])
- 
- ;; if we're still looking around for things to use, here's a last
- ;; ditch effort that just calls the move. We only let this happen
- ;; if we're in the reload pass.
- ;;
- (define_insn ""
-   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,a")
- 	(match_operand:QI 1 "const_int_operand"  "P,i"))]
-   "(reload_in_progress || reload_completed)"
-   "*
- {
-   if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
-       && ! mcore_const_ok_for_inline (INTVAL (operands[1])))
-     {
-       /* mcore_output_move would generate lrw r15 -- a forbidden combo */
-       return mcore_output_inline_const_forced (insn, operands, SImode);
-     }
-   else
-     return mcore_output_move (insn, operands, QImode);
- }"
-   [(set_attr "type" "move")])
  
  ;; DImode
  
--- 1290,1307 ----
      {
        rtx reg = gen_reg_rtx (SImode);
        emit_insn (gen_movsi (reg, operands[1]));
!       operands[1] = gen_lowpart (QImode, reg);
      }
  }")
    
  (define_insn ""
!   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
! 	(match_operand:QI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
    "(register_operand (operands[0], QImode)
!     || register_operand (operands[1], QImode))"
!   "* return mcore_output_move (insn, operands, QImode);"
!    [(set_attr "type" "move,move,move,move,load,store")])
  
  
  ;; DImode
  
*************** (define_expand "movdi"
*** 1502,1516 ****
    else if (GET_CODE (operands[1]) == CONST_INT
             && ! CONST_OK_FOR_I (INTVAL (operands[1]))
  	   && ! CONST_OK_FOR_M (INTVAL (operands[1]))
! 	   && ! CONST_OK_FOR_N (INTVAL (operands[1]))
! 	   && ! reload_completed
! 	   && ! reload_in_progress
! 	   && GET_CODE (operands[0]) == REG)
      {
!       emit_move_insn (operand_subword (operands[0], 0, 1, DImode),
! 	   	      operand_subword_force (operands[1], 0, DImode));
!       emit_move_insn (operand_subword (operands[0], 1, 1, DImode),
! 	  	      operand_subword_force (operands[1], 1, DImode));
        DONE;
      }
  }")
--- 1316,1327 ----
    else if (GET_CODE (operands[1]) == CONST_INT
             && ! CONST_OK_FOR_I (INTVAL (operands[1]))
  	   && ! CONST_OK_FOR_M (INTVAL (operands[1]))
! 	   && ! CONST_OK_FOR_N (INTVAL (operands[1])))
      {
!       int i;
!       for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
!         emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
! 		        simplify_gen_subreg (SImode, operands[1], DImode, i));
        DONE;
      }
  }")
Index: config/mcore/mcore.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.c,v
retrieving revision 1.50
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.50 mcore.c
*** config/mcore/mcore.c	26 Jul 2003 11:27:40 -0000	1.50
--- config/mcore/mcore.c	1 Sep 2003 09:29:48 -0000
*************** mcore_output_move (insn, operands, mode)
*** 1270,1276 ****
  	  if (GET_CODE (XEXP (src, 0)) == LABEL_REF) 
              return "lrw\t%0,[%1]";              /* a-R */
  	  else
!             return "ldw\t%0,%1";                 /* r-m */
  	}
        else if (GET_CODE (src) == CONST_INT)
  	{
--- 1270,1286 ----
  	  if (GET_CODE (XEXP (src, 0)) == LABEL_REF) 
              return "lrw\t%0,[%1]";              /* a-R */
  	  else
! 	    switch (GET_MODE (src))		/* r-m */
! 	      {
! 	      case SImode:
! 		return "ldw\t%0,%1";
! 	      case HImode:
! 		return "ld.h\t%0,%1";
! 	      case QImode:
! 		return "ld.b\t%0,%1";
! 	      default:
! 		abort ();
! 	      }
  	}
        else if (GET_CODE (src) == CONST_INT)
  	{
*************** mcore_output_move (insn, operands, mode)
*** 1291,1390 ****
  	return "lrw\t%0, %1";                /* Into the literal pool.  */
      }
    else if (GET_CODE (dst) == MEM)               /* m-r */
!     return "stw\t%1,%0";
  
    abort ();
  }
  
- /* Outputs a constant inline -- regardless of the cost.
-    Useful for things where we've gotten into trouble and think we'd
-    be doing an lrw into r15 (forbidden). This lets us get out of
-    that pickle even after register allocation.  */
- 
- const char *
- mcore_output_inline_const_forced (insn, operands, mode)
-      rtx insn ATTRIBUTE_UNUSED;
-      rtx operands[];
-      enum machine_mode mode ATTRIBUTE_UNUSED;
- {
-   unsigned long value = INTVAL (operands[1]);
-   unsigned long ovalue = value;
-   struct piece
-   {
-     int low;
-     int shift;
-   }
-   part[6];
-   int i;
- 
-   if (mcore_const_ok_for_inline (value))
-     return output_inline_const (SImode, operands);
- 
-   for (i = 0; (unsigned) i < ARRAY_SIZE (part); i++)
-     {
-       part[i].shift = 0;
-       part[i].low = (value & 0x1F);
-       value -= part[i].low;
-       
-       if (mcore_const_ok_for_inline (value))
- 	break;
-       else
- 	{
- 	  value >>= 5;
- 	  part[i].shift = 5;
- 	  
- 	  while ((value & 1) == 0)
- 	    {
- 	      part[i].shift++;
- 	      value >>= 1;
- 	    }
- 	  
- 	  if (mcore_const_ok_for_inline (value))
- 	    break;
- 	}
-     }
-   
-   /* 5 bits per iteration, a maximum of 5 times == 25 bits and leaves
-      7 bits left in the constant -- which we know we can cover with
-      a movi.  The final value can't be zero otherwise we'd have stopped
-      in the previous iteration.   */
-   if (value == 0 || ! mcore_const_ok_for_inline (value))
-     abort ();
- 
-   /* Now, work our way backwards emitting the constant.  */
- 
-   /* Emit the value that remains -- it will be nonzero.  */
-   operands[1] = GEN_INT (value);
-   output_asm_insn (output_inline_const (SImode, operands), operands);
-  
-   while (i >= 0)
-     {
-       /* Shift anything we've already loaded.  */
-       if (part[i].shift)
-         {
- 	  operands[2] = GEN_INT (part[i].shift);
- 	  output_asm_insn ("lsli       %0,%2", operands);
- 	  value <<= part[i].shift;
-         }
-       
-       /* Add anything we need into the low 5 bits.  */
-       if (part[i].low != 0)
-         {
- 	  operands[2] = GEN_INT (part[i].low);
- 	  output_asm_insn ("addi      %0,%2", operands);
- 	  value += part[i].low;
-         }
-       
-       i--;
-     }
-   
-   if (value != ovalue)          /* sanity */
-     abort ();
-  
-   /* We've output all the instructions.  */
-   return "";
- }
- 
  /* Return a sequence of instructions to perform DI or DF move.
     Since the MCORE cannot move a DI or DF in one instruction, we have
     to take care when we see overlapping source and dest registers.  */
--- 1301,1321 ----
  	return "lrw\t%0, %1";                /* Into the literal pool.  */
      }
    else if (GET_CODE (dst) == MEM)               /* m-r */
!     switch (GET_MODE (dst))
!       {
!       case SImode:
! 	return "stw\t%1,%0";
!       case HImode:
! 	return "st.h\t%1,%0";
!       case QImode:
! 	return "st.b\t%1,%0";
!       default:
! 	abort ();
!       }
  
    abort ();
  }
  
  /* Return a sequence of instructions to perform DI or DF move.
     Since the MCORE cannot move a DI or DF in one instruction, we have
     to take care when we see overlapping source and dest registers.  */
*************** mcore_reorg ()
*** 3064,3099 ****
  }
  
  
! /* Return the reg_class to use when reloading the rtx X into the class
!    CLASS.  */
  
! /* If the input is (PLUS REG CONSTANT) representing a stack slot address,
!    then we want to restrict the class to LRW_REGS since that ensures that
!    will be able to safely load the constant.
  
!    If the input is a constant that should be loaded with mvir1, then use
!    ONLYR1_REGS.
  
!    ??? We don't handle the case where we have (PLUS REG CONSTANT) and
!    the constant should be loaded with mvir1, because that can lead to cases
!    where an instruction needs two ONLYR1_REGS reloads.  */
  enum reg_class
  mcore_reload_class (x, class)
       rtx x;
       enum reg_class class;
  {
!   enum reg_class new_class;
! 
!   if (class == GENERAL_REGS && CONSTANT_P (x)
!       && (GET_CODE (x) != CONST_INT
! 	  || (   ! CONST_OK_FOR_I (INTVAL (x))
! 	      && ! CONST_OK_FOR_M (INTVAL (x))
! 	      && ! CONST_OK_FOR_N (INTVAL (x)))))
!     new_class = LRW_REGS;
!   else
!     new_class = class;
  
!   return new_class;
  }
  
  /* Tell me if a pair of reg/subreg rtx's actually refer to the same
--- 2954,3006 ----
  }
  
  
! /* Return true if X is something that can be moved directly into r15.  */
  
! bool
! mcore_r15_operand_p (x)
!      rtx x;
! {
!   switch (GET_CODE (x))
!     {
!     case CONST_INT:
!       return mcore_const_ok_for_inline (INTVAL (x));
  
!     case REG:
!     case SUBREG:
!     case MEM:
!       return 1;
  
!     default:
!       return 0;
!     }
! }
! 
! /* Implement SECONDARY_RELOAD_CLASS.  If CLASS contains r15, and we can't
!    directly move X into it, use r1-r14 as a temporary.  */
! enum reg_class
! mcore_secondary_reload_class (class, mode, x)
!      enum reg_class class;
!      enum machine_mode mode ATTRIBUTE_UNUSED;
!      rtx x;
! {
!   if (TEST_HARD_REG_BIT (reg_class_contents[class], 15)
!       && !mcore_r15_operand_p (x))
!     return LRW_REGS;
!   return NO_REGS;
! }
! 
! /* Return the reg_class to use when reloading the rtx X into the class
!    CLASS.  If X is too complex to move directly into r15, prefer to
!    use LRW_REGS instead.  */
  enum reg_class
  mcore_reload_class (x, class)
       rtx x;
       enum reg_class class;
  {
!   if (reg_class_subset_p (LRW_REGS, class) && !mcore_r15_operand_p (x))
!     return LRW_REGS;
  
!   return class;
  }
  
  /* Tell me if a pair of reg/subreg rtx's actually refer to the same
Index: config/mcore/mcore.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.h,v
retrieving revision 1.54
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.54 mcore.h
*** config/mcore/mcore.h	21 Aug 2003 17:27:24 -0000	1.54
--- config/mcore/mcore.h	1 Sep 2003 09:29:48 -0000
*************** #define PREFERRED_RELOAD_CLASS(X, CLASS)
*** 603,609 ****
  /* Return the register class of a scratch register needed to copy IN into
     or out of a register in CLASS in MODE.  If it can be done directly,
     NO_REGS is returned.  */
! #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) NO_REGS
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS. 
--- 603,610 ----
  /* Return the register class of a scratch register needed to copy IN into
     or out of a register in CLASS in MODE.  If it can be done directly,
     NO_REGS is returned.  */
! #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
!   mcore_secondary_reload_class (CLASS, MODE, X)
  
  /* Return the maximum number of consecutive registers
     needed to represent mode MODE in a register of class CLASS. 


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