OSDN Git Service

(udivsi3_sh2a, divsi3_sh2a): Give these patterns an "in_delay_slot" attribute
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
index 31e05a2..b725822 100644 (file)
                (match_operand:SI 2 "arith_reg_operand" "z")))]
   "TARGET_SH2A"
   "divu        %2,%1"
-  [(set_attr "type" "arith")])
+  [(set_attr "type" "arith")
+   (set_attr "in_delay_slot" "no")])
 
 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
 ;; hard register 0.  If we used hard register 0, then the next instruction
                (match_operand:SI 2 "arith_reg_operand" "z")))]
   "TARGET_SH2A"
   "divs        %2,%1"
-  [(set_attr "type" "arith")])
+  [(set_attr "type" "arith")
+   (set_attr "in_delay_slot" "no")])
 
 (define_insn "divsi3_i1"
   [(set (match_operand:SI 0 "register_operand" "=z")
              if (GET_MODE (operands[0]) != DImode)
                operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
            }
-         else
+         else if (TARGET_SHMEDIA64)
            {
              operands[0] = shallow_copy_rtx (operands[0]);
              PUT_MODE (operands[0], DImode);
            }
+         else
+           {
+             rtx reg = gen_reg_rtx (DImode);
+
+             operands[0] = copy_to_mode_reg (SImode, operands[0]);
+             emit_insn (gen_extendsidi2 (reg, operands[0]));
+             operands[0] = reg;
+           }
        }
       if (! target_reg_operand (operands[0], DImode))
        operands[0] = copy_to_mode_reg (DImode, operands[0]);
              if (GET_MODE (operands[1]) != DImode)
                operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
            }
-         else
+         else if (TARGET_SHMEDIA64)
            {
              operands[1] = shallow_copy_rtx (operands[1]);
              PUT_MODE (operands[1], DImode);
            }
+         else
+           {
+             rtx reg = gen_reg_rtx (DImode);
+
+             operands[1] = copy_to_mode_reg (SImode, operands[1]);
+             emit_insn (gen_extendsidi2 (reg, operands[1]));
+             operands[1] = reg;
+           }
        }
       if (! target_reg_operand (operands[1], DImode))
        operands[1] = copy_to_mode_reg (DImode, operands[1]);
 
 (define_insn "tls_global_dynamic"
   [(set (match_operand:SI 0 "register_operand" "=&z")
-       (call (unspec:SI [(match_operand:SI 1 "" "")]
-                         UNSPEC_TLSGD)
+       (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
+                                 UNSPEC_TLSGD))
              (const_int 0)))
    (use (reg:PSI FPSCR_REG))
    (use (reg:SI PIC_REG))
@@ -6882,8 +6900,8 @@ mov.l\\t1f,r4\\n\\
 
 (define_insn "tls_local_dynamic"
   [(set (match_operand:SI 0 "register_operand" "=&z")
-       (call (unspec:SI [(match_operand:SI 1 "" "")]
-                         UNSPEC_TLSLDM)
+       (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
+                                 UNSPEC_TLSLDM))
              (const_int 0)))
    (use (reg:PSI FPSCR_REG))
    (use (reg:SI PIC_REG))
@@ -9431,7 +9449,7 @@ mov.l\\t1f,r0\\n\\
        (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
                         (match_operand 2 "const_int_operand" "")
                         (match_operand 3 "const_int_operand" "")))]
-  ""
+  "TARGET_SH4A_ARCH"
 {
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
@@ -9451,7 +9469,7 @@ mov.l\\t1f,r0\\n\\
        (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
                         (match_operand 2 "const_int_operand" "")
                         (match_operand 3 "const_int_operand" "")))]
-  ""
+  "TARGET_SH4A_ARCH"
 {
   if (TARGET_SH4A_ARCH
       && INTVAL (operands[2]) == 32
@@ -10935,17 +10953,45 @@ mov.l\\t1f,r0\\n\\
   "byterev     %1, %0"
   [(set_attr "type" "arith_media")])
 
-(define_insn "prefetch"
+(define_insn "prefetch_media"
   [(prefetch (match_operand:QI 0 "address_operand" "p")
              (match_operand:SI 1 "const_int_operand" "n")
              (match_operand:SI 2 "const_int_operand" "n"))]
-  "TARGET_SHMEDIA || TARGET_HARD_SH4"
+  "TARGET_SHMEDIA"
   "*
 {
-  if (TARGET_HARD_SH4)
-    return \"pref @%0\";
   operands[0] = gen_rtx_MEM (QImode, operands[0]);
   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
   return \"\";
 }"
   [(set_attr "type" "other")])
+
+(define_insn "prefetch_i4"
+  [(prefetch (match_operand:SI 0 "register_operand" "r")
+             (match_operand:SI 1 "const_int_operand" "n")
+             (match_operand:SI 2 "const_int_operand" "n"))]
+  "TARGET_HARD_SH4"
+  "*
+{
+  return \"pref @%0\";
+}"
+  [(set_attr "type" "other")])
+
+(define_expand "prefetch"
+  [(prefetch (match_operand:QI 0 "address_operand" "p")
+             (match_operand:SI 1 "const_int_operand" "n")
+             (match_operand:SI 2 "const_int_operand" "n"))]
+  "TARGET_SHMEDIA || TARGET_HARD_SH4"
+  "
+{
+  if (TARGET_HARD_SH4 && ! register_operand (operands[0], SImode))
+    {
+      rtx reg = gen_reg_rtx (SImode);
+      emit_move_insn (reg, operands[0]);
+      operands[0] = reg;
+    }
+
+  emit_insn ((TARGET_SHMEDIA ? gen_prefetch_media : gen_prefetch_i4)
+            (operands[0], operands[1], operands[2]));
+  DONE;
+}")