re PR target/49878 ([h8300] ICE in based_loc_descr, at dwarf2out.c:10478)
[gcc.git] / gcc / config / h8300 / h8300.md
index db56e20cbbe436d63baadc9b795257faef196a0f..fa1809dfa77dc66ea5bf573337303907af65c3d7 100644 (file)
 
 (include "predicates.md")
 (include "constraints.md")
+\f
+;; ----------------------------------------------------------------------
+;; MACRO DEFINITIONS
+;; ----------------------------------------------------------------------
+
+;; This mode iterator allows :P to be used for patterns that operate on
+;; pointer-sized quantities.  Exactly one of the two alternatives will match.
+(define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
+
 \f
 ;; ----------------------------------------------------------------------
 ;; MOVE INSTRUCTIONS
   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
        (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
   "TARGET_H8300
-   && (register_operand (operands[0], QImode)
-       || register_operand (operands[1], QImode))"
+   && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.b       %X0,%X0
    mov.b       %R1,%X0
   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
        (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
-   && (register_operand (operands[0], QImode)
-       || register_operand (operands[1], QImode))"
+   && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.b       %X0,%X0
    mov.b       %R1,%X0
   [(set (match_operand:QI 0 "general_operand_dst" "")
        (match_operand:QI 1 "general_operand_src" ""))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
-  if (!TARGET_H8300SX
-      && !register_operand (operand0, QImode)
-      && !register_operand (operand1, QImode))
-    {
-      operands[1] = copy_to_mode_reg (QImode, operand1);
-    }
-}")
+  if (!TARGET_H8300SX && !h8300_move_ok (operands[0], operands[1]))
+    operands[1] = copy_to_mode_reg (QImode, operands[1]);
+})
 
 (define_insn "movstrictqi"
   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
        (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
   "TARGET_H8300
-   && (register_operand (operands[0], HImode)
-       || register_operand (operands[1], HImode))
-   && !(GET_CODE (operands[0]) == MEM
-       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
-       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
-       && GET_CODE (operands[1]) == REG
-       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
+   && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.w       %T0,%T0
    mov.w       %T1,%T0
   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
        (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
-   && (register_operand (operands[0], HImode)
-       || register_operand (operands[1], HImode))"
+   && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.w       %T0,%T0
    mov.w       %T1,%T0
   [(set (match_operand:HI 0 "general_operand_dst" "")
        (match_operand:HI 1 "general_operand_src" ""))]
   ""
-  "
 {
   /* One of the ops has to be in a register.  */
-  if (!register_operand (operand1, HImode)
-      && !register_operand (operand0, HImode))
-    {
-      operands[1] = copy_to_mode_reg (HImode, operand1);
-    }
-}")
+  if (!h8300_move_ok (operands[0], operands[1]))
+    operands[1] = copy_to_mode_reg (HImode, operand1);
+})
 
 (define_insn "movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
   [(set (match_operand:SI 0 "general_operand_dst" "")
        (match_operand:SI 1 "general_operand_src" ""))]
   ""
-  "
 {
   if (TARGET_H8300)
     {
   else if (!TARGET_H8300SX)
     {
       /* One of the ops has to be in a register.  */
-      if (!register_operand (operand1, SImode)
-         && !register_operand (operand0, SImode))
-       {
-         operands[1] = copy_to_mode_reg (SImode, operand1);
-       }
+      if (!h8300_move_ok (operands[0], operands[1]))
+       operands[1] = copy_to_mode_reg (SImode, operand1);
     }
-}")
+})
 
 (define_insn "*movsi_h8300"
   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
        (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
   "TARGET_H8300
-   && (register_operand (operands[0], SImode)
-       || register_operand (operands[1], SImode))"
+   && h8300_move_ok (operands[0], operands[1])"
   "*
 {
   unsigned int rn = -1;
   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
        (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
   "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
-   && (register_operand (operands[0], SImode)
-       || register_operand (operands[1], SImode))
-   && !(GET_CODE (operands[0]) == MEM
-       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
-       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
-       && GET_CODE (operands[1]) == REG
-       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
+   && h8300_move_ok (operands[0], operands[1])"
   "*
 {
   switch (which_alternative)
 ;; PUSH INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "pushqi1_h8300"
-  [(set (reg:HI SP_REG)
-       (plus:HI (reg:HI SP_REG) (const_int -2)))
-   (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1)))
-       (match_operand:QI 0 "register_operand" "r"))]
-  "TARGET_H8300
-   && operands[0] != stack_pointer_rtx"
+(define_insn "*pushqi1_h8300"
+  [(set (mem:QI
+         (pre_modify:HI
+           (reg:HI SP_REG)
+           (plus:HI (reg:HI SP_REG) (const_int -2))))
+       (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
+  "TARGET_H8300"
   "mov.w\\t%T0,@-r7"
   [(set_attr "length" "2")])
 
-(define_insn "pushqi1_h8300hs_advanced"
-  [(set (reg:SI SP_REG)
-       (plus:SI (reg:SI SP_REG) (const_int -4)))
-   (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
-       (match_operand:QI 0 "register_operand" "r"))]
-  "(TARGET_H8300H || TARGET_H8300S)
-   && operands[0] != stack_pointer_rtx"
-  "mov.l\\t%S0,@-er7"
-  [(set_attr "length" "4")])
-
-(define_insn "pushqi1_h8300hs_normal"
-  [(set (reg:HI SP_REG)
-       (plus:HI (reg:HI SP_REG) (const_int -4)))
-   (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
-       (match_operand:QI 0 "register_operand" "r"))]
-  "(TARGET_H8300H || TARGET_H8300S)
-   && operands[0] != stack_pointer_rtx"
-  "mov.l\\t%S0,@-er7"
-  [(set_attr "length" "4")])
-
-(define_expand "pushqi1"
-  [(match_operand:QI 0 "register_operand" "")]
-  ""
-  "
-{
-  if (TARGET_H8300)
-    emit_insn (gen_pushqi1_h8300 (operands[0]));
-  else if (!TARGET_NORMAL_MODE)
-    emit_insn (gen_pushqi1_h8300hs_advanced (operands[0]));
-  else
-    emit_insn (gen_pushqi1_h8300hs_normal (operands[0]));
-  DONE;
-}")
-
-(define_expand "pushhi1_h8300"
-  [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
-       (match_operand:HI 0 "register_operand" ""))]
-  "TARGET_H8300
-   && operands[0] != stack_pointer_rtx"
-  "")
-
-(define_insn "pushhi1_h8300hs_advanced"
-  [(set (reg:SI SP_REG)
-       (plus:SI (reg:SI SP_REG) (const_int -4)))
-   (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
-       (match_operand:HI 0 "register_operand" "r"))]
-  "(TARGET_H8300H || TARGET_H8300S)
-   && operands[0] != stack_pointer_rtx"
+(define_insn "*pushqi1_h8300hs_<mode>"
+  [(set (mem:QI
+         (pre_modify:P
+           (reg:P SP_REG)
+           (plus:P (reg:P SP_REG) (const_int -4))))
+       (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
+  "TARGET_H8300H || TARGET_H8300S"
   "mov.l\\t%S0,@-er7"
   [(set_attr "length" "4")])
 
-(define_insn "pushhi1_h8300hs_normal"
-  [(set (reg:HI SP_REG)
-       (plus:HI (reg:HI SP_REG) (const_int -4)))
-   (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
-       (match_operand:HI 0 "register_operand" "r"))]
-  "(TARGET_H8300H || TARGET_H8300S)
-   && operands[0] != stack_pointer_rtx"
+(define_insn "*pushhi1_h8300hs_<mode>"
+  [(set (mem:HI
+         (pre_modify:P
+           (reg:P SP_REG)
+           (plus:P (reg:P SP_REG) (const_int -4))))
+       (match_operand:HI 0 "register_no_sp_elim_operand" "r"))]
+  "TARGET_H8300H || TARGET_H8300S"
   "mov.l\\t%S0,@-er7"
   [(set_attr "length" "4")])
-
-(define_expand "pushhi1"
-  [(match_operand:HI 0 "register_operand" "")]
-  ""
-  "
-{
-  if (TARGET_H8300)
-    emit_insn (gen_pushhi1_h8300 (operands[0]));
-  else if (!TARGET_NORMAL_MODE)
-    emit_insn (gen_pushhi1_h8300hs_advanced (operands[0]));
-  else
-    emit_insn (gen_pushhi1_h8300hs_normal (operands[0]));
-  DONE;
-}")
 \f
 ;; ----------------------------------------------------------------------
 ;; TEST INSTRUCTIONS