re PR target/44755 (picochip.md enum types mismatch)
[gcc.git] / gcc / config / picochip / picochip.md
index e1f3b388f68ee7004d5bbda493df43de3dfb27a3..2a59c074cac5070be9b428da865154ac41541886 100644 (file)
    ; Internal TSTPORT instruction, used to generate a single TSTPORT
    ; instruction for use in the testport branch split.
    (UNSPEC_INTERNAL_TESTPORT        19)
-
-   ; instruction for use in the profile based optimizations.
-   (UNSPEC_INTERNAL_PROFILE        20)
   ]
 )
 
 (define_insn_and_split "cbranchhi4"
   [(set (pc)
         (if_then_else
-            (match_operator:CC 0 "comparison_operator"
+            (match_operator:CC 0 "ordered_comparison_operator"
                             [(match_operand:HI 1 "register_operand" "r")
                              (match_operand:HI 2 "picochip_comparison_operand" "ri")])
             (label_ref       (match_operand    3 "" ""))
    (set_attr "length" "2,2,4")
    ])
 
+;; This pattern was added to match the previous pattern. When doing if-convert
+;; the pattern generated using movhicc does not have a eq:CC but only a eq for
+;; operator. If this pattern were not to be there, Gcc decides not to use
+;; movhicc at all. Whereas, in Gcc 4.4, it seems to be cleverer.
+(define_insn "*supported_compare1"
+  [(set (reg:CC CC_REGNUM)
+        (match_operator 0 "picochip_supported_comparison_operator"
+                        [(match_operand:HI 1 "register_operand" "r,r,r")
+                         (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
+  ""
+  "* return picochip_output_compare(operands);"
+  [; Must be picoAlu because it sets the condition flags.
+   (set_attr "type" "picoAlu,picoAlu,picoAlu")
+   (set_attr "longConstant" "false,false,true")
+   (set_attr "length" "2,2,4")
+   ])
+
 (define_insn "*compare"
   [(set (reg:CC CC_REGNUM)
         (match_operator:CC 0 "comparison_operator"
 
 ; Match a branch instruction, created from a tstport/cbranch split.
 ; We use a "use" clause so GCC doesnt try to use this pattern generally.
-(define_insn "*branch"
+(define_insn "branch"
   [(set (pc)
         (if_then_else
             (match_operator 2 "comparison_operator"
        rtx shiftVal;
        rtx loadedValue;
        rtx addressMask;
+       rtx topByteValue;
+       rtx signExtendedValue;
+
 
        warn_of_byte_access();
 
          emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
 
         /* Shift the desired byte to the most significant byte. */
-        rtx topByteValue = gen_reg_rtx (HImode);
+        topByteValue = gen_reg_rtx (HImode);
         emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal));
 
          /* Sign extend the top-byte back into the bottom byte. */
-        rtx signExtendedValue = gen_reg_rtx(HImode);
+        signExtendedValue = gen_reg_rtx(HImode);
          emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8)));
 
          /* Final extraction of QI mode register. */
        {
          rtx zeroingByteMask;
          rtx temp;
-         rtx tempQiMode;
          rtx tempHiMode;
+         rtx lsbByteMask;
 
          /* Get the address. */
          address = gen_reg_rtx(HImode);
          * bits, instead of the original memory value which is being
          * modified.
          */
-         /*if (register_operand(operands[1],QImode))
-         {
-           tempHiMode = XEXP(operands[1], 0);
-         }
-         else
-         {
-           tempHiMode = operands[1];
-         }*/
-         //tempHiMode = force_reg(QImode, operands[1]);
          tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0);
          temp = gen_reg_rtx(HImode);
         emit_insn(gen_rtx_SET(HImode, temp, tempHiMode));
-         rtx lsbByteMask = gen_reg_rtx (HImode);
+         lsbByteMask = gen_reg_rtx (HImode);
         emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF)));
         emit_insn (gen_andhi3 (temp, temp, lsbByteMask));
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
         (match_operand:SI 1 "const_int_operand" ""))]
-  ""
+  "reload_completed"
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 4) (match_dup 5))]
   "{
     // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0
     STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1")
 
+;; memcpy pattern
+;; 0 = destination (mem:BLK ...)
+;; 1 = source (mem:BLK ...)
+;; 2 = count
+;; 3 = alignment
+(define_expand "movmemhi"
+  [(match_operand 0 "memory_operand" "")
+  (match_operand 1 "memory_operand" "")
+  (match_operand:HI 2 "immediate_operand" "")
+  (match_operand 3 "" "")]
+  "picochip_schedule_type != DFA_TYPE_NONE"
+  "if (picochip_expand_movmemhi(operands)) DONE; FAIL;"
+)
+
 ;;===========================================================================
 ;; NOP
 ;;===========================================================================
   {
     /* Synthesise a variable shift. */
 
+    rtx tmp1;
+    rtx tmp2;
+    rtx tmp3;
+    rtx minus_one;
+    rtx tmp4;
+
     /* Fill a temporary with the sign bits. */
-    rtx tmp1 = gen_reg_rtx (HImode);
+    tmp1 = gen_reg_rtx (HImode);
     emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15)));
 
     /* Shift the unsigned value. */
-    rtx tmp2 = gen_reg_rtx (HImode);
+    tmp2 = gen_reg_rtx (HImode);
     emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2]));
 
     /* The word of sign bits must be shifted back to the left, to zero
      * count). Since the shifts are computed modulo 16 (i.e., only the
      * lower 4 bits of the count are used), the shift amount (15 - count)
      * is equivalent to !count. */
-    rtx tmp3 = gen_reg_rtx (HImode);
-    rtx tmp3_1 = GEN_INT (-1);
-    emit_insn (gen_xorhi3 (tmp3, operands[2], tmp3_1));
-    rtx tmp4 = gen_reg_rtx (HImode);
+    tmp3 = gen_reg_rtx (HImode);
+    minus_one = GEN_INT (-1);
+    emit_insn (gen_xorhi3 (tmp3, operands[2], minus_one));
+    tmp4 = gen_reg_rtx (HImode);
     emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3));
 
     /* Combine the sign bits with the shifted value. */
   [(set_attr "length" "1")
    (set_attr "type" "unknown")])
 
-(define_insn "profile"
-  [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "i")]
-       UNSPEC_INTERNAL_PROFILE)]
-  ""
-  "PROFILE_DUMMY %0 \t// (profile instruction %0)"
-  [(set_attr "length" "1")
-   (set_attr "type" "unknown")])
-
 (define_insn "internal_testport"
   [(set (reg:CC CC_REGNUM)
         (unspec_volatile:CC [(match_operand:HI 0 "const_int_operand" "i")]
                   UNSPEC_TESTPORT))
    (clobber (reg:CC CC_REGNUM))]
   ""
-  "// %0 := TestPort(%1)\;TSTPORT %1\;COPYSW.0 %0\;AND.0 %0,8,%0"
+  "// %0 := TestPort(%1)\;COPY.1 0,%0 %| TSTPORT %1\;COPYEQ 1,%0"
   [(set_attr "length" "9")])
 
 ; Entry point for array tstport (the actual port index is computed as the
 ;;============================================================================
 
 ;; Define expand seems to consider the resulting two instructions to be
-;; independent. It was moving the actual copy instruction further down
-;; with a call instruction in between. The call was clobbering the CC
-;; and hence the cond_copy was wrong. With a split, it works correctly.
+;; independent. With a split, guarded by reload, it works correctly.
 (define_expand "movhicc"
-  [(set (reg:CC CC_REGNUM) (match_operand 1 "comparison_operator" ""))
-   (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
-                   (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
-                                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
-                                 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
-              (use (match_dup 4))])]
+   [(set (match_operand:HI 0 "register_operand" "=r,r")
+                   (if_then_else:HI (match_operand:HI 1 "" "")
+                  (match_operand:HI 2 "register_operand" "0,0")
+                  (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
   ""
   {if (!picochip_check_conditional_copy (operands))
      FAIL;
-   operands[4] = GEN_INT(GET_CODE(operands[1]));
   })
 
+(define_insn_and_split "*checked_movhicc"
+   [(set (match_operand:HI 0 "register_operand" "=r,r")
+                   (if_then_else:HI (match_operator 1 "picochip_peephole_comparison_operator"
+                          [(match_operand:HI 4 "register_operand" "r,r")
+                           (match_operand:HI 5 "picochip_comparison_operand" "r,i")])
+                  (match_operand:HI 2 "register_operand" "0,0")
+                  (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:CC CC_REGNUM) (match_dup 1))
+   (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
+                   (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
+                                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
+                                 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
+              (use (match_dup 6))])]
+  "{
+     operands[6] = GEN_INT(GET_CODE(operands[0]));
+   }")
+
 ;; We dont do any checks here. But this pattern is used only when movhicc 
 ;; was checked. Put a "use" clause to make sure.
 (define_insn "*conditional_copy"
        (if_then_else:HI
             (match_operator:HI 4 "picochip_peephole_comparison_operator"
                  [(reg:CC CC_REGNUM) (const_int 0)])
-        (match_operand:HI 1 "picochip_register_or_immediate_operand" "0,0")
+        (match_operand:HI 1 "register_operand" "0,0")
         (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,i")))
    (use (match_operand:HI 3 "const_int_operand" ""))]
   ""
    (set_attr "type" "picoAlu,picoAlu")
    (set_attr "longConstant" "false,true")])
 
-;; cmphi - This needs to be defined, to ensure that the conditional
-;; move works properly (because the if-cvt code uses this pattern to
-;; build the conditional move, even though normally we use cbranch to
-;; directly generate the instructions).
-
-(define_expand "cmphi"
-  [(match_operand:HI 0 "general_operand" "g")
-   (match_operand:HI 1 "general_operand" "g")]
-  ""
-  "DONE;")
-
-;;============================================================================
-;; Branch patterns - needed for conditional moves.  This is because
-;; they result in the bcc_gen_fctn array being initialised with the
-;; code to define_expand the following, and this in turn means that
-;; when noce_emit_cmove is called, the correct pattern can be
-;; generated, based upon the assumed presence of the following.  The
-;; following are never actually used, because the earlier cbranch
-;; patterns take precendence.
-;;============================================================================
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else
-           (ne (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else
-           (eq (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else
-           (lt (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else
-           (ge (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else
-           (geu (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else
-           (ltu (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else
-           (le (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else
-           (gt (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else
-           (leu (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else
-           (gtu (reg:CC CC_REGNUM) (const_int 0))
-           (label_ref       (match_operand    0 "" ""))
-           (pc)))]
-  ""
-  "gcc_unreachable();")
-
 ;;============================================================================
 ;; Scheduling, including delay slot scheduling.
 ;;============================================================================
   (const_string "unknown"))
 
 (define_attr "schedType" "none,space,speed"
-  (const (symbol_ref "picochip_schedule_type")))
+  (const (symbol_ref "(enum attr_schedType) picochip_schedule_type")))
 
 ;; Define whether an instruction uses a long constant.