am33 port

Jeffrey A Law law@cygnus.com
Wed Dec 1 16:22:00 GMT 1999


The am33 is basically a mn10300 on steroids -- it adds 8 general purpose
registers (desperately needed), a couple new multiply instructions and
has post-increment addressing modes.

Nothing particularly complex here, the mn103 port is rather simple and
straightforward, the am33 extensions aren't overly complex either.

[ In case anyone is curious, a mn103 chip drives the personal dvd players
  from Panasonic that started appearing in the US 12-18 months ago.  Not
  sure if the am33 has hit any consumer products in the US yet.  ]

        * mn10300.c (REG_SAVE_BYTES): Allocate space for AM33 registers.
        (asm_file_start): Emit .am33 into assembly file when compiling for
        the AM33.
        (print_operand_address): Handle POST_INC addresses.
        (can_use_return_insn, initial_offset): Check AM33 registers too.
        (expand_prologue): Check & save AM33 registers too.
        (expand_epilogue): Similarly.
        (secondary_reload_class): Handle AM33 specific secondary reloads.
        (output_tst): Emit efficient code for the AM33 too.
        * mn10300.h (CPP_SPEC, TARGET_AM33): Define.
        (TARGET_SWITCHES): Add -mam33 switch.
        (FIRST_PSEUDO_REGISTER): Handle new AM33 registers.
        (FIXED_REGISTERS, CALL_USED_REGISTERS): Likewise.
        (REG_ALLOC_ORDER, CONDITIONAL_REGISTER_USAGE): Likewise.
        (HARD_REGNO_MODE_OK, MODES_TIEABLE_P): Likewise.
        (enum reg_class, REG_CLASS_NAMES): Likewise.
        (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Likewise.
        (INDEX_REG_CLASS, REG_CLASS_FROM_LETTER): Likewise.
        (REGNO_OK_FOR_INDEX_P, PREFERRED_RELOAD_CLASS): Likewise.
        (PREFERRED_OUTPUT_RELOAD_CLASS, LIMIT_RELOAD_CLASS): Likewise.
        (REGISTER_MOVE_COST, REGISTER_NAMES): Likewise.
        (HAVE_POST_INCREMENT): Define.
        (GO_IF_LEGITIMATE_ADDRESS): Allow POST_INC addresses for the AM33.
        (GO_IF_MODE_DEPENDENT_ADDRESS): POST_INC is a mode dependent address.
        * mn10300.md (movqi, movhi, addsi, subsi): Add AM33 variants.
        (mulsi, andsi, iorsi, xorsi, notsi): Likewise.
        (ashiftsi, lshiftrtsi, ashiftrtsi): Likewise.
        (zero_extend to SI from QI/HI): Likewise.
        (sign_extend to SI from QI/HI): Likewise.
        (mulsidi3, umulsidi3): New patterns for the AM33.
        (tstsi with zero extension from QI/HI): Add AM33 variants.
        (movsi, movsf, movdi, movdf): Generate efficient code for the AM33 too.
        (return_internal_regs, store_movm): Handle new AM33 registers.
        * t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Define.
        (LIBGCC, INSTALL_LIBGCC): Likewise.
        * invoke.texi: Document new flags.
Index: invoke.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/invoke.texi,v
retrieving revision 1.156
diff -c -3 -p -r1.156 invoke.texi
*** invoke.texi	1999/11/30 23:26:37	1.156
--- invoke.texi	1999/12/02 00:08:29
*************** in the following sections.
*** 291,296 ****
--- 291,298 ----
  @emph{MN10300 Options}
  -mmult-bug
  -mno-mult-bug
+ -mam33
+ -mno-am33
  -mrelax
  
  @emph{M32R/D Options}
*************** processors.  This is the default.
*** 4640,4645 ****
--- 4642,4655 ----
  @item -mno-mult-bug
  Do not generate code to avoid bugs in the multiply instructions for the
  MN10300 processors.
+ 
+ @table @code
+ @item -mam33
+ Generate code which uses features specific to the AM33 processor.
+ 
+ @item -mno-am33
+ Do not generate code which uses features specific to the AM33 processor.  
This
+ is the default.
  
  @item -mrelax
  Indicate to the linker that it should perform a relaxation optimization pass
Index: config/mn10300/mn10300.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mn10300/mn10300.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 mn10300.c
*** mn10300.c	1999/09/12 01:51:28	1.19
--- mn10300.c	1999/12/02 00:08:30
*************** Boston, MA 02111-1307, USA.  */
*** 42,49 ****
     speed standpoint, so we want to optimize this sooner or later.  */
  #define REG_SAVE_BYTES (4 * regs_ever_live[2] \
  			+ 4 * regs_ever_live[3] \
! 			+ 4 * regs_ever_live[6] \
! 			+ 4 * regs_ever_live[7])
  
  void
  asm_file_start (file)
--- 42,51 ----
     speed standpoint, so we want to optimize this sooner or later.  */
  #define REG_SAVE_BYTES (4 * regs_ever_live[2] \
  			+ 4 * regs_ever_live[3] \
! 		        + 4 * regs_ever_live[6] \
! 			+ 4 * regs_ever_live[7] \
! 			+ 16 * (regs_ever_live[14] || regs_ever_live[15] \
! 				|| regs_ever_live[16] || regs_ever_live[17]))
  
  void
  asm_file_start (file)
*************** asm_file_start (file)
*** 54,59 ****
--- 56,64 ----
      fprintf (file, "# -O%d\n", optimize);
    else
      fprintf (file, "\n\n");
+ 
+   if (TARGET_AM33)
+     fprintf (file, "\t.am33\n");
    output_file_directive (file, main_input_filename);
  }
  
*************** print_operand_address (file, addr)
*** 312,317 ****
--- 317,326 ----
  {
    switch (GET_CODE (addr))
      {
+     case POST_INC:
+       print_operand_address (file, XEXP (addr, 0));
+       fputc ('+', file);
+       break;
      case REG:
        if (addr == stack_pointer_rtx)
  	print_operand_address (file, gen_rtx_PLUS (SImode,
*************** can_use_return_insn ()
*** 360,365 ****
--- 369,378 ----
  	  && !regs_ever_live[3]
  	  && !regs_ever_live[6]
  	  && !regs_ever_live[7]
+ 	  && !regs_ever_live[14]
+ 	  && !regs_ever_live[15]
+ 	  && !regs_ever_live[16]
+ 	  && !regs_ever_live[17]
  	  && !frame_pointer_needed);
  }
  
*************** expand_prologue ()
*** 388,393 ****
--- 401,408 ----
       single two byte instruction.  */
    if (regs_ever_live[2] || regs_ever_live[3]
        || regs_ever_live[6] || regs_ever_live[7]
+       || regs_ever_live[14] || regs_ever_live[15]
+       || regs_ever_live[16] || regs_ever_live[17]
        || frame_pointer_needed)
      emit_insn (gen_store_movm ());
  
*************** expand_epilogue ()
*** 432,437 ****
--- 447,454 ----
        size = 0;
      }
    else if ((regs_ever_live[2] || regs_ever_live[3]
+ 	    || regs_ever_live[14] || regs_ever_live[15]
+ 	    || regs_ever_live[16] || regs_ever_live[17]
  	    || regs_ever_live[6] || regs_ever_live[7])
  	   && size + REG_SAVE_BYTES > 255)
      {
*************** expand_epilogue ()
*** 448,453 ****
--- 465,472 ----
       stack requirements and is faster.  */
    if (regs_ever_live[2] || regs_ever_live[3]
        || regs_ever_live[6] || regs_ever_live[7]
+       || regs_ever_live[14] || regs_ever_live[15]
+       || regs_ever_live[16] || regs_ever_live[17]
        || frame_pointer_needed)
      emit_jump_insn (gen_return_internal_regs (GEN_INT (size + 
REG_SAVE_BYTES)));
    else
*************** secondary_reload_class (class, mode, in)
*** 554,559 ****
--- 573,580 ----
        && (mode == QImode || mode == HImode)
        && (class == ADDRESS_REGS || class == SP_REGS))
      {
+       if (TARGET_AM33)
+ 	return DATA_OR_EXTENDED_REGS;
        return DATA_REGS;
      }
  
*************** secondary_reload_class (class, mode, in)
*** 562,567 ****
--- 583,591 ----
    if (class != SP_REGS
        && class != ADDRESS_REGS
        && class != SP_OR_ADDRESS_REGS
+       && class != SP_OR_EXTENDED_REGS
+       && class != ADDRESS_OR_EXTENDED_REGS
+       && class != SP_OR_ADDRESS_OR_EXTENDED_REGS
        && (in == stack_pointer_rtx
  	  || (GET_CODE (in) == PLUS
  	      && (XEXP (in, 0) == stack_pointer_rtx
*************** secondary_reload_class (class, mode, in)
*** 572,577 ****
--- 596,603 ----
        && (XEXP (in, 0) == stack_pointer_rtx
  	  || XEXP (in, 1) == stack_pointer_rtx))
      {
+       if (TARGET_AM33)
+ 	return DATA_OR_EXTENDED_REGS;
        return DATA_REGS;
      }
   
*************** initial_offset (from, to)
*** 589,594 ****
--- 615,622 ----
      {
        if (regs_ever_live[2] || regs_ever_live[3]
  	  || regs_ever_live[6] || regs_ever_live[7]
+ 	  || regs_ever_live[14] || regs_ever_live[15]
+ 	  || regs_ever_live[16] || regs_ever_live[17]
  	  || frame_pointer_needed)
  	return REG_SAVE_BYTES;
        else
*************** initial_offset (from, to)
*** 602,607 ****
--- 630,637 ----
      {
        if (regs_ever_live[2] || regs_ever_live[3]
  	  || regs_ever_live[6] || regs_ever_live[7]
+ 	  || regs_ever_live[14] || regs_ever_live[15]
+ 	  || regs_ever_live[16] || regs_ever_live[17]
  	  || frame_pointer_needed)
  	return (get_frame_size () + REG_SAVE_BYTES
  		+ (current_function_outgoing_args_size
*************** output_tst (operand, insn)
*** 855,860 ****
--- 885,910 ----
  	  && !reg_set_between_p (SET_DEST (set), temp, insn)
  	  && (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
  	      == REGNO_REG_CLASS (REGNO (operand)))
+ 	  && REGNO_REG_CLASS (REGNO (SET_DEST (set))) != EXTENDED_REGS
+ 	  && REGNO (SET_DEST (set)) != REGNO (operand)
+ 	  && (!past_call 
+ 	      || !call_used_regs[REGNO (SET_DEST (set))]))
+ 	{
+ 	  rtx xoperands[2];
+ 	  xoperands[0] = operand;
+ 	  xoperands[1] = SET_DEST (set);
+ 
+ 	  output_asm_insn ("cmp %1,%0", xoperands);
+ 	  return "";
+ 	}
+ 
+       if (REGNO_REG_CLASS (REGNO (operand)) == EXTENDED_REGS
+ 	  && REG_P (SET_DEST (set))
+ 	  && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
+ 	  && !reg_set_between_p (SET_DEST (set), temp, insn)
+ 	  && (REGNO_REG_CLASS (REGNO (SET_DEST (set)))
+ 	      != REGNO_REG_CLASS (REGNO (operand)))
+ 	  && REGNO_REG_CLASS (REGNO (SET_DEST (set))) == EXTENDED_REGS
  	  && REGNO (SET_DEST (set)) != REGNO (operand)
  	  && (!past_call 
  	      || !call_used_regs[REGNO (SET_DEST (set))]))
Index: config/mn10300/mn10300.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mn10300/mn10300.h,v
retrieving revision 1.21
diff -c -3 -p -r1.21 mn10300.h
*** mn10300.h	1999/09/07 05:48:50	1.21
--- mn10300.h	1999/12/02 00:08:36
*************** Boston, MA 02111-1307, USA.  */
*** 32,37 ****
--- 32,39 ----
  
  #define CPP_PREDEFINES "-D__mn10300__ -D__MN10300__"
  
+ #define CPP_SPEC "%{mam33:-D__AM33__}"
+ 
  /* Run-time compilation parameters selecting different hardware subsets.  */
  
  extern int target_flags;
*************** extern int target_flags;
*** 46,54 ****
--- 48,63 ----
  
  /* Generate code to work around mul/mulq bugs on the mn10300.  */
  #define TARGET_MULT_BUG			(target_flags & 0x1)
+ 
+ /* Generate code for the AM33 processor.  */
+ #define TARGET_AM33			(target_flags & 0x2)
+ 
  #define TARGET_SWITCHES  \
    {{ "mult-bug",	0x1,  "Work around hardware multiply bug"},	\
     { "no-mult-bug", 	-0x1, "Do not work around hardware multiply bug"},\
+    { "am33", 		0x2},	\
+    { "am33", 		-(0x1)},\
+    { "no-am33", 	-0x2},	\
     { "", TARGET_DEFAULT, NULL}}
  
  #ifndef TARGET_DEFAULT
*************** extern int target_flags;
*** 134,146 ****
     All registers that the compiler knows about must be given numbers,
     even those that are not normally considered general registers.  */
  
! #define FIRST_PSEUDO_REGISTER 10
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.  */
  
  #define FIXED_REGISTERS \
!   { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
--- 143,155 ----
     All registers that the compiler knows about must be given numbers,
     even those that are not normally considered general registers.  */
  
! #define FIRST_PSEUDO_REGISTER 18
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.  */
  
  #define FIXED_REGISTERS \
!   { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
  
  /* 1 for registers not available across function calls.
     These must include the FIXED_REGISTERS and also any
*************** extern int target_flags;
*** 151,160 ****
     like.  */
  
  #define CALL_USED_REGISTERS \
!   { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}
  
  #define REG_ALLOC_ORDER \
!   { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9}
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
--- 160,178 ----
     like.  */
  
  #define CALL_USED_REGISTERS \
!   { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}
  
  #define REG_ALLOC_ORDER \
!   { 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9}
! 
! #define CONDITIONAL_REGISTER_USAGE \
! {						\
!   if (!TARGET_AM33)				\
!     {						\
!       for (i = 10; i < 18; i++) 		\
! 	fixed_regs[i] = call_used_regs[i] = 1; 	\
!     }						\
! }
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
*************** extern int target_flags;
*** 169,175 ****
     MODE.  */
  
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
!  (REGNO_REG_CLASS (REGNO) == DATA_REGS 			\
    ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4	\
    : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
  
--- 187,195 ----
     MODE.  */
  
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
!  ((REGNO_REG_CLASS (REGNO) == DATA_REGS \
!    || (TARGET_AM33 && REGNO_REG_CLASS (REGNO) == ADDRESS_REGS) \
!    || REGNO_REG_CLASS (REGNO) == EXTENDED_REGS) \
    ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4	\
    : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
  
*************** extern int target_flags;
*** 178,184 ****
     If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
     for any hard reg, then this must be 0 for correct output.  */
  #define MODES_TIEABLE_P(MODE1, MODE2) \
!   (MODE1 == MODE2 || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 
4))
  
  /* 4 data, and effectively 3 address registers is small as far as I'm
     concerned.  */
--- 198,206 ----
     If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
     for any hard reg, then this must be 0 for correct output.  */
  #define MODES_TIEABLE_P(MODE1, MODE2) \
!   (TARGET_AM33  \
!    || MODE1 == MODE2 \
!    || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
  
  /* 4 data, and effectively 3 address registers is small as far as I'm
     concerned.  */
*************** extern int target_flags;
*** 207,212 ****
--- 229,236 ----
  enum reg_class {
    NO_REGS, DATA_REGS, ADDRESS_REGS, SP_REGS,
    DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS, 
+   EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS,
+   SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS, 
    GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
  };
  
*************** enum reg_class {
*** 217,222 ****
--- 241,249 ----
  #define REG_CLASS_NAMES \
  { "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
    "SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
+   "EXTENDED_REGS", \
+   "DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
+   "SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
    "GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
  
  /* Define which registers fit in which classes.
*************** enum reg_class {
*** 225,237 ****
  
  #define REG_CLASS_CONTENTS  			\
  {      0,		/* No regs      */	\
!    0x00f,		/* DATA_REGS */		\
!    0x1f0,		/* ADDRESS_REGS */	\
!    0x200,		/* SP_REGS */		\
!    0x1ff,		/* DATA_OR_ADDRESS_REGS */\
!    0x1f0,		/* SP_OR_ADDRESS_REGS */\
!    0x1ff,		/* GENERAL_REGS */    	\
!    0x3ff,		/* ALL_REGS 	*/	\
  }
  
  /* The same information, inverted:
--- 252,269 ----
  
  #define REG_CLASS_CONTENTS  			\
  {      0,		/* No regs      */	\
!    0x0000f,		/* DATA_REGS */		\
!    0x001f0,		/* ADDRESS_REGS */	\
!    0x00200,		/* SP_REGS */		\
!    0x001ff,		/* DATA_OR_ADDRESS_REGS */\
!    0x003f0,		/* SP_OR_ADDRESS_REGS */\
!    0x2fc00,		/* EXTENDED_REGS */	\
!    0x2fc0f,		/* DATA_OR_EXTENDED_REGS */	\
!    0x2fdf0,		/* ADDRESS_OR_EXTENDED_REGS */	\
!    0x2fe00,		/* SP_OR_EXTENDED_REGS */	\
!    0x2fff0,		/* SP_OR_ADDRESS_OR_EXTENDED_REGS */	\
!    0x2fdff,		/* GENERAL_REGS */    	\
!    0x2ffff,		/* ALL_REGS 	*/	\
  }
  
  /* The same information, inverted:
*************** enum reg_class {
*** 242,251 ****
  #define REGNO_REG_CLASS(REGNO) \
    ((REGNO) < 4 ? DATA_REGS : \
     (REGNO) < 9 ? ADDRESS_REGS : \
!     (REGNO) == 9 ? SP_REGS : 0)
  
  /* The class value for index registers, and the one for base regs.  */
! #define INDEX_REG_CLASS DATA_REGS
  #define BASE_REG_CLASS  SP_OR_ADDRESS_REGS
  
  /* Get reg_class from a letter such as appears in the machine description.  
*/
--- 274,284 ----
  #define REGNO_REG_CLASS(REGNO) \
    ((REGNO) < 4 ? DATA_REGS : \
     (REGNO) < 9 ? ADDRESS_REGS : \
!     (REGNO) == 9 ? SP_REGS : \
!      (REGNO) < 18 ? EXTENDED_REGS : 0)
  
  /* The class value for index registers, and the one for base regs.  */
! #define INDEX_REG_CLASS DATA_OR_EXTENDED_REGS
  #define BASE_REG_CLASS  SP_OR_ADDRESS_REGS
  
  /* Get reg_class from a letter such as appears in the machine description.  
*/
*************** enum reg_class {
*** 253,258 ****
--- 286,292 ----
  #define REG_CLASS_FROM_LETTER(C) \
    ((C) == 'd' ? DATA_REGS : \
     (C) == 'a' ? ADDRESS_REGS : \
+    (C) == 'x' ? EXTENDED_REGS : \
     (C) == 'y' ? SP_REGS : NO_REGS)
  
  /* Macros to check register numbers against specific register classes.  */
*************** enum reg_class {
*** 273,278 ****
--- 307,314 ----
  
  #define REGNO_OK_FOR_INDEX_P(regno) \
    (((regno) >= 0 && regno < 4)	\
+    || ((regno) >= 10 && regno < 18)	\
+    || (reg_renumber[regno] >= 10 && reg_renumber[regno] < 18) \
     || (reg_renumber[regno] >= 0 && reg_renumber[regno] < 4))
  
  
*************** enum reg_class {
*** 282,294 ****
     in some cases it is preferable to use a more restrictive class.  */
  
  #define PREFERRED_RELOAD_CLASS(X,CLASS) \
!   (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
  
  #define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) \
!   (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
  
  #define LIMIT_RELOAD_CLASS(MODE, CLASS) \
!   ((MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
  
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class(CLASS,MODE,IN)
--- 318,332 ----
     in some cases it is preferable to use a more restrictive class.  */
  
  #define PREFERRED_RELOAD_CLASS(X,CLASS) \
!   (X == stack_pointer_rtx && CLASS != SP_REGS \
!    ? ADDRESS_OR_EXTENDED_REGS : CLASS)
  
  #define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) \
!   (X == stack_pointer_rtx && CLASS != SP_REGS \
!    ? ADDRESS_OR_EXTENDED_REGS : CLASS)
  
  #define LIMIT_RELOAD_CLASS(MODE, CLASS) \
!   (!TARGET_AM33 && (MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
  
  #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
    secondary_reload_class(CLASS,MODE,IN)
*************** extern struct rtx_def *mn10300_va_arg();
*** 645,650 ****
--- 683,690 ----
  #endif
  
  
+ #define HAVE_POST_INCREMENT (TARGET_AM33)
+ 
  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
     that is a valid memory address for an instruction.
     The MODE argument is the machine mode for the MEM expression
*************** extern struct rtx_def *mn10300_va_arg();
*** 678,683 ****
--- 718,728 ----
      goto ADDR;						\
    if (RTX_OK_FOR_BASE_P (X))				\
      goto ADDR;						\
+   if (TARGET_AM33					\
+       && GET_CODE (X) == POST_INC			\
+       && RTX_OK_FOR_BASE_P (XEXP (X, 0))		\
+       && (MODE == SImode || MODE == SFmode || MODE == HImode))\
+     goto ADDR;						\
    if (GET_CODE (X) == PLUS)				\
      {							\
        rtx base = 0, index = 0;				\
*************** extern struct rtx_def *legitimize_addres
*** 719,725 ****
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */
  
! #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)  {}
  
  /* Nonzero if the constant value X is a legitimate general operand.
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
--- 764,772 ----
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */
  
! #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)        \
!   if (GET_CODE (ADDR) == POST_INC) \
!     goto LABEL
  
  /* Nonzero if the constant value X is a legitimate general operand.
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
*************** extern struct rtx_def *legitimize_addres
*** 771,779 ****
       so their cost is very high.  */					\
    case CONST_DOUBLE:							\
      return 8;
- 
  
! #define REGISTER_MOVE_COST(CLASS1, CLASS2)  (CLASS1 != CLASS2 ? 4 : 2)
  
  /* A crude cut at RTX_COSTS for the MN10300.  */
  
--- 818,827 ----
       so their cost is very high.  */					\
    case CONST_DOUBLE:							\
      return 8;
  
! #define REGISTER_MOVE_COST(CLASS1, CLASS2) \
!   ((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 
:\
!    CLASS1 == CLASS2 && CLASS1 == EXTENDED_REGS ? 6 : 4)
  
  /* A crude cut at RTX_COSTS for the MN10300.  */
  
*************** do { char dstr[30];					\
*** 923,929 ****
     This sequence is indexed by compiler's hard-register-number (see above).  
*/
  
  #define REGISTER_NAMES \
! { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp" }
  
  /* Print an instruction operand X on file FILE.
     look in mn10300.c for details */
--- 971,978 ----
     This sequence is indexed by compiler's hard-register-number (see above).  
*/
  
  #define REGISTER_NAMES \
! { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
!   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }
  
  /* Print an instruction operand X on file FILE.
     look in mn10300.c for details */
Index: config/mn10300/mn10300.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mn10300/mn10300.md,v
retrieving revision 1.25
diff -c -3 -p -r1.25 mn10300.md
*** mn10300.md	1999/10/18 19:59:48	1.25
--- mn10300.md	1999/12/02 00:08:36
***************
*** 56,61 ****
--- 56,107 ----
  }")
  
  (define_insn ""
+   [(set (match_operand:QI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
+ 	(match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
+   "TARGET_AM33
+    && (register_operand (operands[0], QImode)
+        || register_operand (operands[1], QImode))"
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+     case 1:
+       return \"nop\";
+     case 2:
+       return \"clr %0\";
+     case 3:
+     case 4:
+     case 5:
+     case 6:
+     case 7:
+       if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  rtx xoperands[2];
+ 	  xoperands[0] = operands[0];
+ 	  xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ 	  output_asm_insn (\"mov %1,%0\", xoperands);
+ 	  return \"\";
+ 	}
+ 
+       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
+ 	  && GET_CODE (operands[1]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT val = INTVAL (operands[1]);
+ 
+ 	  if (((val & 0x80) && ! (val & 0xffffff00))
+ 	      || ((val & 0x800000) && ! (val & 0xff000000)))
+ 	    return \"movu %1,%0\";
+ 	}
+       return \"mov %1,%0\";
+     case 8:
+     case 9:
+       return \"movbu %1,%0\";
+     }
+ }"
+   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,
none_0hit,none_0hit,none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:QI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m"
)
  	(match_operand:QI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
    "register_operand (operands[0], QImode)
***************
*** 106,111 ****
--- 152,203 ----
  }")
  
  (define_insn ""
+   [(set (match_operand:HI 0 "general_operand" "=dx,a,dx,a,dx,a,dx,a,dxa,m")
+ 	(match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dxa"))]
+   "TARGET_AM33
+    && (register_operand (operands[0], HImode)
+        || register_operand (operands[1], HImode))"
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+     case 1:
+       return \"nop\";
+     case 2:
+       return \"clr %0\";
+     case 3:
+     case 4:
+     case 5:
+     case 6:
+     case 7:
+       if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  rtx xoperands[2];
+ 	  xoperands[0] = operands[0];
+ 	  xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ 	  output_asm_insn (\"mov %1,%0\", xoperands);
+ 	  return \"\";
+ 	}
+ 
+       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
+ 	  && GET_CODE (operands[1]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT val = INTVAL (operands[1]);
+ 
+ 	  if (((val & 0x80) && ! (val & 0xffffff00))
+ 	      || ((val & 0x800000) && ! (val & 0xff000000)))
+ 	    return \"movu %1,%0\";
+ 	}
+       return \"mov %1,%0\";
+     case 8:
+     case 9:
+       return \"movhu %1,%0\";
+     }
+ }"
+   [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,
none_0hit,none_0hit,none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:HI 0 "general_operand" "=dx,*a,dx,*a,dx,*a,dx,*a,dx,m"
)
  	(match_operand:HI 1 "general_operand" "0,0,I,I,a,dx,dxi,ia,m,dx"))]
    "register_operand (operands[0], HImode)
***************
*** 229,234 ****
--- 321,336 ----
  	  output_asm_insn (\"mov %1,%0\", xoperands);
  	  return \"\";
  	}
+ 
+       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
+ 	  && GET_CODE (operands[1]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT val = INTVAL (operands[1]);
+ 
+ 	  if (((val & 0x80) && ! (val & 0xffffff00))
+ 	      || ((val & 0x800000) && ! (val & 0xff000000)))
+ 	    return \"movu %1,%0\";
+ 	}
        return \"mov %1,%0\";
      }
  }"
***************
*** 263,268 ****
--- 365,379 ----
      case 3:
      case 4:
      case 5:
+       if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
+ 	  && GET_CODE (operands[1]) == CONST_INT)
+ 	{
+ 	  HOST_WIDE_INT val = INTVAL (operands[1]);
+ 
+ 	  if (((val & 0x80) && ! (val & 0xffffff00))
+ 	      || ((val & 0x800000) && ! (val & 0xff000000)))
+ 	    return \"movu %1,%0\";
+ 	}
        return \"mov %1,%0\";
      }
  }"
***************
*** 376,381 ****
--- 487,497 ----
  		else
  		  output_asm_insn (\"mov %L1,%L0\", operands);
  	      }
+ 	    else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
+ 		      == EXTENDED_REGS)
+ 		     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
+ 			 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
+ 	      output_asm_insn (\"movu %1,%0\", operands);
  	    else
  	      output_asm_insn (\"mov %L1,%L0\", operands);
  
***************
*** 392,397 ****
--- 508,518 ----
  		      || GET_CODE (operands[1]) == CONST_DOUBLE)
  		     && val[0] == val[1])
  	      output_asm_insn (\"mov %L0,%H0\", operands);
+ 	    else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
+ 		      == EXTENDED_REGS)
+ 		     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
+ 			 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
+ 	      output_asm_insn (\"movu %1,%0\", operands);
  	    else
  	      output_asm_insn (\"mov %H1,%H0\", operands);
  	    return \"\";
***************
*** 508,513 ****
--- 629,639 ----
  		else
  		  output_asm_insn (\"mov %L1,%L0\", operands);
  	      }
+ 	    else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
+ 		      == EXTENDED_REGS)
+ 		     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
+ 			 || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
+ 	      output_asm_insn (\"movu %1,%0\", operands);
  	    else
  	      output_asm_insn (\"mov %L1,%L0\", operands);
  
***************
*** 524,529 ****
--- 650,660 ----
  		      || GET_CODE (operands[1]) == CONST_DOUBLE)
  		     && val[0] == val[1])
  	      output_asm_insn (\"mov %L0,%H0\", operands);
+ 	    else if ((REGNO_REG_CLASS (true_regnum (operands[0]))
+ 		      == EXTENDED_REGS)
+ 		     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
+ 			 || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
+ 	      output_asm_insn (\"movu %1,%0\", operands);
  	    else
  	      output_asm_insn (\"mov %H1,%H0\", operands);
  	    return \"\";
***************
*** 547,564 ****
    [(set_attr "cc" "set_znv")])
  
  (define_insn ""
    [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
    ""
    "* return output_tst (operands[0], insn);"
    [(set_attr "cc" "set_znv")])
  
  (define_insn ""
    [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
    ""
    "* return output_tst (operands[0], insn);"
    [(set_attr "cc" "set_znv")])
  
- 
  (define_insn "cmpsi"
    [(set (cc0)
  	(compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
--- 678,706 ----
    [(set_attr "cc" "set_znv")])
  
  (define_insn ""
+   [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" 
"dx,!a")))]
+   "TARGET_AM33"
+   "* return output_tst (operands[0], insn);"
+   [(set_attr "cc" "set_znv")])
+ 
+ (define_insn ""
    [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
    ""
    "* return output_tst (operands[0], insn);"
    [(set_attr "cc" "set_znv")])
  
  (define_insn ""
+   [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" 
"dx,!a")))]
+   "TARGET_AM33"
+   "* return output_tst (operands[0], insn);"
+   [(set_attr "cc" "set_znv")])
+ 
+ (define_insn ""
    [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
    ""
    "* return output_tst (operands[0], insn);"
    [(set_attr "cc" "set_znv")])
  
  (define_insn "cmpsi"
    [(set (cc0)
  	(compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
***************
*** 597,602 ****
--- 739,820 ----
    [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
  	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
  		 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+     case 1:
+       return \"inc %0\";
+     case 2:
+       return \"inc4 %0\";
+     case 3:
+     case 4:
+       return \"add %2,%0\";
+     case 5:
+       {
+ 	enum reg_class src1_class, src2_class, dst_class;
+ 
+ 	src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
+ 	src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
+ 	dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
+ 	
+ 	/* I'm not sure if this can happen or not.  Might as well be prepared
+ 	  and generate the best possible code if it does happen.  */
+ 	if (true_regnum (operands[0]) == true_regnum (operands[1]))
+ 	  return \"add %2,%0\";
+ 	if (true_regnum (operands[0]) == true_regnum (operands[2]))
+ 	  return \"add %1,%0\";
+ 
+ 	/* Catch cases where no extended register was used.  These should be
+ 	   handled just like the mn10300.  */
+ 	if (src1_class != EXTENDED_REGS
+ 	    && src2_class != EXTENDED_REGS
+ 	    && dst_class != EXTENDED_REGS)
+ 	  {
+ 	    /* We have to copy one of the sources into the destination, then
+ 	       add the other source to the destination.
+ 
+ 	       Carefully select which source to copy to the destination; a naive
+ 	       implementation will waste a byte when the source classes are 
+ 	       different and the destination is an address register.  Selecting
+ 	       the lowest cost register copy will optimize this sequence.  */
+ 	    if (REGNO_REG_CLASS (true_regnum (operands[1]))
+ 		== REGNO_REG_CLASS (true_regnum (operands[0])))
+ 	      return \"mov %1,%0\;add %2,%0\";
+ 	    return \"mov %2,%0\;add %1,%0\";
+ 	  }
+ 
+ 	/* At least one register is an extended register.  */
+ 
+ 	/* The three operand add instruction on the am33 is a win iff the
+ 	   output register is an extended register, or if both source
+ 	   registers are extended registers.  */
+ 	if (dst_class == EXTENDED_REGS
+ 	    || src1_class == src2_class)
+ 	  return \"add %2,%1,%0\";
+ 
+       /* It is better to copy one of the sources to the destination, then
+ 	 perform a 2 address add.  The destination in this case must be
+ 	 an address or data register and one of the sources must be an
+ 	 extended register and the remaining source must not be an extended
+ 	 register.
+ 
+ 	 The best code for this case is to copy the extended reg to the
+ 	 destination, then emit a two address add.  */
+       if (src1_class == EXTENDED_REGS)
+ 	return \"mov %1,%0\;add %2,%0\";
+       return \"mov %2,%0\;add %1,%0\";
+       }
+     }
+ }"
+   [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,ax,ax,dax,xy,!dax")
+ 	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
+ 		 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
    ""
    "*
  {
***************
*** 645,650 ****
--- 863,898 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
+ 	(minus:SI (match_operand:SI 1 "register_operand" "0,dax")
+ 		  (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (true_regnum (operands[0]) == true_regnum (operands[1]))
+     return \"sub %2,%0\";
+   else
+     {
+       enum reg_class src1_class, src2_class, dst_class;
+ 
+       src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
+       src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
+       dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
+ 
+       /* If no extended registers are used, then the best way to handle
+ 	 this is to copy the first source operand into the destination
+ 	 and emit a two address subtraction.  */
+       if (src1_class != EXTENDED_REGS
+ 	  && src2_class != EXTENDED_REGS
+ 	  && dst_class != EXTENDED_REGS
+ 	  && true_regnum (operands[0]) != true_regnum (operands[2]))
+ 	return \"mov %1,%0\;sub %2,%0\";
+       return \"sub %2,%1,%0\";
+     }
+ }"
+   [(set_attr "cc" "set_zn")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dax")
  	(minus:SI (match_operand:SI 1 "register_operand" "0")
  		  (match_operand:SI 2 "nonmemory_operand" "daxi")))]
***************
*** 670,675 ****
--- 918,939 ----
  ;; MULTIPLY INSTRUCTIONS
  ;; ----------------------------------------------------------------------
  
+ (define_insn "mulsidi3"
+   [(set (match_operand:DI 0 "register_operand" "=dax")
+         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" 
"dax"))
+                  (sign_extend:DI (match_operand:SI 2 "register_operand" 
"dax"))))]
+   "TARGET_AM33"
+   "mul %1,%2,%H0,%L0"
+   [(set_attr "cc" "set_zn")])
+ 
+ (define_insn "umulsidi3"
+   [(set (match_operand:DI 0 "register_operand" "=dax")
+         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" 
"dax"))
+                  (zero_extend:DI (match_operand:SI 2 "register_operand" 
"dax"))))]
+   "TARGET_AM33"
+   "mulu %1,%2,%H0,%L0"
+   [(set_attr "cc" "set_zn")])
+ 
  (define_expand "mulsi3"
    [(set (match_operand:SI 0 "register_operand" "")
  	(mult:SI (match_operand:SI 1 "register_operand" "")
***************
*** 678,683 ****
--- 942,961 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+ 	(mult:SI (match_operand:SI 1 "register_operand" "%0,0")
+ 		 (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (TARGET_MULT_BUG)
+     return \"nop\;nop\;mul %2,%0\";
+   else
+     return \"mul %2,%0\";
+ }"
+   [(set_attr "cc" "set_zn")])
+   
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(mult:SI (match_operand:SI 1 "register_operand" "%0")
  		 (match_operand:SI 2 "register_operand" "dx")))]
***************
*** 738,743 ****
--- 1016,1066 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
+ 	(and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
+ 		(match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
+     return \"extbu %0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
+     return \"exthu %0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0x7fffffff)
+     return \"add %0,%0\;lsr 1,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0x3fffffff)
+     return \"asl2 %0\;lsr 2,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0x1fffffff)
+     return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0x0fffffff)
+     return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0xfffffffe)
+     return \"lsr 1,%0\;add %0,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0xfffffffc)
+     return \"lsr 2,%0\;asl2 %0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0xfffffff8)
+     return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 
0xfffffff0)
+     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2])
+       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
+     return \"mov %1,%0\;and %2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"and %1,%2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[0])
+       && true_regnum (operands[2]) == true_regnum (operands[0]))
+     return \"and %1,%0\";
+   return \"and %2,%0\";
+ }"
+   [(set_attr "cc" "none_0hit,set_znv,set_znv")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx,dx")
  	(and:SI (match_operand:SI 1 "register_operand" "%0,0")
  		(match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
***************
*** 780,785 ****
--- 1103,1133 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+ 	(ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
+ 		(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2])
+       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
+     return \"mov %1,%0\;or %2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"or %1,%2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[0])
+       && true_regnum (operands[2]) == true_regnum (operands[0]))
+     return \"or %1,%0\";
+   return \"or %2,%0\";
+ }"
+   [(set_attr "cc" "set_znv")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(ior:SI (match_operand:SI 1 "register_operand" "%0")
  		(match_operand:SI 2 "nonmemory_operand" "dxi")))]
***************
*** 799,804 ****
--- 1147,1177 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+ 	(xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
+ 		(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2])
+       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
+     return \"mov %1,%0\;xor %2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[1])
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"xor %1,%2,%0\";
+   if (REG_P (operands[2]) && REG_P (operands[0])
+       && true_regnum (operands[2]) == true_regnum (operands[0]))
+     return \"xor %1,%0\";
+   return \"xor %2,%0\";
+ }"
+   [(set_attr "cc" "set_znv")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(xor:SI (match_operand:SI 1 "register_operand" "%0")
  		(match_operand:SI 2 "nonmemory_operand" "dxi")))]
***************
*** 815,821 ****
  	(not:SI (match_operand:SI 1 "register_operand" "")))]
    ""
    "")
!  
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(not:SI (match_operand:SI 1 "register_operand" "0")))]
--- 1188,1201 ----
  	(not:SI (match_operand:SI 1 "register_operand" "")))]
    ""
    "")
! 
! (define_insn ""
!   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
! 	(not:SI (match_operand:SI 1 "register_operand" "0,0")))]
!   "TARGET_AM33"
!   "not %0"
!   [(set_attr "cc" "set_znv")])
! 
  (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(not:SI (match_operand:SI 1 "register_operand" "0")))]
***************
*** 1215,1220 ****
--- 1595,1614 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
+ 	(zero_extend:SI
+ 	 (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
+   "TARGET_AM33"
+   "@
+   extbu %0
+   mov %1,%0\;extbu %0
+   movbu %1,%0
+   extbu %0
+   mov %1,%0\;extbu %0
+   movbu %1,%0"
+   [(set_attr "cc" "none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
  	(zero_extend:SI
  	 (match_operand:QI 1 "general_operand" "0,d,m")))]
***************
*** 1233,1238 ****
--- 1627,1646 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx,!dax,!dax,!dax")
+ 	(zero_extend:SI
+ 	 (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
+   "TARGET_AM33"
+   "@
+   exthu %0
+   mov %1,%0\;exthu %0
+   movhu %1,%0
+   exthu %0
+   mov %1,%0\;exthu %0
+   movhu %1,%0"
+   [(set_attr "cc" "none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=dx,dx,dx")
  	(zero_extend:SI
  	 (match_operand:HI 1 "general_operand" "0,dx,m")))]
***************
*** 1253,1258 ****
--- 1661,1678 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
+ 	(sign_extend:SI
+ 	 (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
+   "TARGET_AM33"
+   "@
+   extb %0
+   mov %1,%0\;extb %0
+   extb %0
+   mov %1,%0\;extb %0"
+   [(set_attr "cc" "none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=dx,dx")
  	(sign_extend:SI
  	 (match_operand:QI 1 "general_operand" "0,dx")))]
***************
*** 1270,1275 ****
--- 1690,1707 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=dx,dx,!dax,!dax")
+ 	(sign_extend:SI
+ 	 (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
+   "TARGET_AM33"
+   "@
+   exth %0
+   mov %1,%0\;exth %0
+   exth %0
+   mov %1,%0\;exth %0"
+   [(set_attr "cc" "none_0hit")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=dx,dx")
  	(sign_extend:SI
  	 (match_operand:HI 1 "general_operand" "0,dx")))]
***************
*** 1292,1297 ****
--- 1724,1762 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
+ 	(ashift:SI
+ 	 (match_operand:SI 1 "register_operand" "0,0,dax")
+ 	 (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
+     return \"add %0,%0\";
+ 
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
+     return \"asl2 %0\";
+ 
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
+       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
+     return \"asl2 %0\;add %0,%0\";
+ 
+   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
+       && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
+     return \"asl2 %0\;asl2 %0\";
+ 
+   if (true_regnum (operands[1]) == true_regnum (operands[0]))
+     return \"asl %S2,%0\";
+ 
+   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"mov %1,%0\;asl %S2,%0\";
+   return \"asl %2,%1,%0\";
+ }"
+   [(set_attr "cc" "set_zn")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
  	(ashift:SI
  	 (match_operand:SI 1 "register_operand" "0,0,0,0,0")
***************
*** 1314,1319 ****
--- 1779,1803 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+ 	(lshiftrt:SI
+ 	 (match_operand:SI 1 "register_operand" "0,dax")
+ 	 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (true_regnum (operands[1]) == true_regnum (operands[0]))
+     return \"lsr %S2,%0\";
+ 
+   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"mov %1,%0\;lsr %S2,%0\";
+   return \"lsr %2,%1,%0\";
+ }"
+   [(set_attr "cc" "set_zn")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(lshiftrt:SI
  	 (match_operand:SI 1 "register_operand" "0")
***************
*** 1331,1336 ****
--- 1815,1839 ----
    "")
  
  (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+ 	(ashiftrt:SI
+ 	 (match_operand:SI 1 "register_operand" "0,dax")
+ 	 (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
+   "TARGET_AM33"
+   "*
+ {
+   if (true_regnum (operands[1]) == true_regnum (operands[0]))
+     return \"asr %S2,%0\";
+ 
+   if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
+       && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
+       && true_regnum (operands[0]) != true_regnum (operands[2]))
+     return \"mov %1,%0\;asr %S2,%0\";
+   return \"asr %2,%1,%0\";
+ }"
+   [(set_attr "cc" "set_zn")])
+ 
+ (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=dx")
  	(ashiftrt:SI
  	 (match_operand:SI 1 "register_operand" "0")
***************
*** 1495,1500 ****
--- 1998,2004 ----
  {
    int i, need_comma;
    int d2, d3, a2, a3;
+   int exreg1;
  
    need_comma = 0;
    fputs (\"\\tret [\", asm_out_file);
***************
*** 1524,1529 ****
--- 2028,2041 ----
        fputs (\"a3\", asm_out_file);
        need_comma = 1;
      }
+   if (regs_ever_live[14] || regs_ever_live[15]
+       || regs_ever_live[16] || regs_ever_live[17])
+     {
+       if (need_comma)
+ 	fputc (',', asm_out_file); 
+       fputs (\"exreg1\", asm_out_file);
+       need_comma = 1;
+     }
    fprintf (asm_out_file, \"],%d\\n\", INTVAL (operands[0]));
    return \"\";
  }"
***************
*** 1536,1541 ****
--- 2048,2054 ----
  {
    int i, need_comma;
    int d2, d3, a2, a3;
+   int exreg1;
  
    need_comma = 0;
    fputs (\"\\tmovm [\", asm_out_file);
***************
*** 1563,1568 ****
--- 2076,2089 ----
        if (need_comma)
  	fputc (',', asm_out_file); 
        fputs (\"a3\", asm_out_file);
+       need_comma = 1;
+     }
+   if (regs_ever_live[14] || regs_ever_live[15]
+       || regs_ever_live[16] || regs_ever_live[17])
+     {
+       if (need_comma)
+ 	fputc (',', asm_out_file); 
+       fputs (\"exreg1\", asm_out_file);
        need_comma = 1;
      }
    fputs (\"],(sp)\\n\", asm_out_file);
Index: config/mn10300/t-mn10300
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mn10300/t-mn10300,v
retrieving revision 1.4
diff -c -3 -p -r1.4 t-mn10300
*** t-mn10300	1999/08/05 03:27:48	1.4
--- t-mn10300	1999/12/02 00:08:36
*************** fp-bit.c: $(srcdir)/config/fp-bit.c
*** 18,20 ****
--- 18,26 ----
  	echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
  	echo '#endif' 		>> fp-bit.c
  	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+ 
+ MULTILIB_OPTIONS = mam33
+ MULTILIB_DIRNAMES = am33 
+ 
+ LIBGCC = stmp-multilib
+ INSTALL_LIBGCC = install-multilib





More information about the Gcc-patches mailing list