[PATCH] [MIPS] [Loongson] Specific integer instructions added ( How to test ’prefetchx‘?)

Ruan Beihong ruanbeihong@gmail.com
Mon Jul 21 10:05:00 GMT 2008


This patch is based on gcc-4.4 r137685.
Following Loongson 2[E|F] specific integer instructions have been added.
multu.g dmultu.g div.g ddiv.g  divu.g ddivu.g mod.g dmod.g modu.g dmodu.g
Those instruction execute 3 integer operands mult, div and mod without
using or changing HI/LO.

By the way, I tried to add prefetch (load to $0 on Loongson) and
prefetchx (split to an plus operation and a prefetch),
 but I failed to construct a C code which gcc can generate the
'prefetchx'. So I ask for help that some one interested
might change this poor patch and test the 'prefetchx' then release a
formal patch.

Patch below:
Index: gcc/config/mips/loongson.md
===================================================================
--- gcc/config/mips/loongson.md (版本 137685)
+++ gcc/config/mips/loongson.md (工作副本)
@@ -473,3 +473,31 @@
   "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
   "punpckl<V_stretch_half_suffix>\t%0,%1,%2"
   [(set_attr "type" "fdiv")])
+
+
+;;new integer instructions
+
+(define_insn "<u>div<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+       (any_div:GPR
+               (match_operand:GPR 1 "register_operand" "d")
+               (match_operand:GPR 2 "register_operand" "d")))]
+  "TARGET_LOONGSON_2EF"
+  { return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); }
+  [(set_attr "type" "idiv3")
+   (set_attr "mode" "<MODE>")]
+)
+
+(define_code_iterator any_mod [mod umod])
+
+(define_insn "<u>mod<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+       (any_mod:GPR
+               (match_operand:GPR 1 "register_operand" "d")
+               (match_operand:GPR 2 "register_operand" "d")))]
+  "TARGET_LOONGSON_2EF"
+  { return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); }
+  [(set_attr "type" "idiv3")
+   (set_attr "mode" "<MODE>")]
+)
+
Index: gcc/config/mips/loongson2ef.md
===================================================================
--- gcc/config/mips/loongson2ef.md      (版本 137685)
+++ gcc/config/mips/loongson2ef.md      (工作副本)
@@ -160,14 +160,14 @@
 ;; Reservation for integer multiplication instructions.
 (define_insn_reservation "ls2_imult" 5
   (and (eq_attr "cpu" "loongson_2e,loongson_2f")
-       (eq_attr "type" "imul,imul3"))
+       (eq_attr "type" "imul,imul3,imul3_ls2ef"))
   "ls2_alu2,ls2_alu2_core")

 ;; Reservation for integer division / remainder instructions.
 ;; These instructions use the SRT algorithm and hence take 2-38 cycles.
 (define_insn_reservation "ls2_idiv" 20
   (and (eq_attr "cpu" "loongson_2e,loongson_2f")
-       (eq_attr "type" "idiv"))
+       (eq_attr "type" "idiv,idiv3"))
   "ls2_alu2,ls2_alu2_core*18")

 ;; Reservation for memory load instructions.
@@ -176,6 +176,11 @@
        (eq_attr "type" "load,fpload,mfc,mtc"))
   "ls2_mem")

+(define_insn_reservation "ls2_prefetch" 0
+  (and (eq_attr "cpu" "loongson_2e,loongson_2f")
+       (eq_attr "type" "prefetch,prefetchx"))
+  "ls2_mem")
+
 ;; Reservation for memory store instructions.
 ;; With stores we assume they don't alias with dependent loads.
 ;; Therefore we set the latency to zero.
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md     (版本 137685)
+++ gcc/config/mips/mips.md     (工作副本)
@@ -346,8 +346,10 @@
 ;; trap                trap if instructions
 ;; imul                integer multiply 2 operands
 ;; imul3       integer multiply 3 operands
+;; imul3_ls2ef integer multiply 3 operands for loongson_2ef
 ;; imadd       integer multiply-add
-;; idiv                integer divide
+;; idiv                integer divide 2 operands
+;; idiv                integer divide 3 operands
 ;; move                integer register move ({,D}ADD{,U} with rt = 0)
 ;; fmove       floating point register move
 ;; fadd                floating point add/subtract
@@ -371,7 +373,7 @@
 (define_attr "type"
   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
    prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical,
-   shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,
+   shift,slt,signext,clz,trap,imul,imul3,imul3_ls2ef,imadd,idiv,idiv3,move,fmove,fadd,fmul,
    fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,
    frsqrt2,multi,nop,ghost"
   (cond [(eq_attr "jal" "!unset") (const_string "call")
@@ -546,7 +548,7 @@
                    (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
          (const_int 8)

-         (eq_attr "type" "idiv")
+         (eq_attr "type" "idiv,idiv3")
          (symbol_ref "mips_idiv_insns () * 4")
          ] (const_int 4)))

@@ -788,6 +790,7 @@
 ;; "u" when doing an unsigned operation.
 (define_code_attr u [(sign_extend "") (zero_extend "u")
                     (div "") (udiv "u")
+                    (mod "") (umod "u")
                     (gt "") (gtu "u")
                     (ge "") (geu "u")
                     (lt "") (ltu "u")
@@ -1291,7 +1294,9 @@
                 (match_operand:SI 2 "register_operand")))]
   ""
 {
-  if (ISA_HAS_MUL3)
+  if (TARGET_LOONGSON_2EF)
+    emit_insn (gen_mulsi3_mult3_ls2ef (operands[0], operands[1], operands[2]));
+  else if (ISA_HAS_MUL3)
     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
   else if (TARGET_FIX_R4000)
     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
@@ -1306,13 +1311,35 @@
                 (match_operand:DI 2 "register_operand")))]
   "TARGET_64BIT"
 {
-  if (TARGET_FIX_R4000)
+  if (TARGET_LOONGSON_2EF)
+    emit_insn (gen_muldi3_mult3_ls2ef (operands [0], operands[1],
operands[2]));
+  else if (TARGET_FIX_R4000)
     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
   else
     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
   DONE;
 })

+(define_insn "mulsi3_mult3_ls2ef"
+  [(set (match_operand:SI 0 "register_operand" "=d" )
+       (mult:SI
+               (match_operand:SI 1 "register_operand" "d")
+               (match_operand:SI 2 "register_operand" "d")))]
+  "TARGET_LOONGSON_2EF"
+  "multu.g\t%0,%1,%2"
+  [(set_attr "type" "imul3_ls2ef")
+   (set_attr "mode" "SI")])
+
+(define_insn "muldi3_mult3_ls2ef"
+  [(set (match_operand:DI 0 "register_operand" "=d" )
+       (mult:DI
+               (match_operand:DI 1 "register_operand" "d")
+               (match_operand:DI 2 "register_operand" "d")))]
+  "TARGET_LOONGSON_2EF"
+  "dmultu.g\t%0,%1,%2"
+  [(set_attr "type" "imul3_ls2ef")
+   (set_attr "mode" "DI")])
+
 (define_insn "mulsi3_mult3"
   [(set (match_operand:SI 0 "register_operand" "=d,l")
        (mult:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -2306,7 +2333,7 @@
   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
   [(set_attr "type" "idiv")
    (set_attr "mode" "<GPR:MODE>")])
-

+
 ;;
 ;;  ....................
 ;;
@@ -6335,27 +6362,59 @@

 (define_insn "prefetch"
   [(prefetch (match_operand:QI 0 "address_operand" "p")
-            (match_operand 1 "const_int_operand" "n")
-            (match_operand 2 "const_int_operand" "n"))]
+       (match_operand 1 "const_int_operand" "n")
+       (match_operand 2 "const_int_operand" "n"))]
   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
 {
+  if(TARGET_LOONGSON_2EF)
+  /*Loongson 2[ef] use load to $0 to perform prefetching*/
+    return "ld\t$0,%a0";
   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
-  return "pref\t%1,%a0";
+    return "pref\t%1,%a0";
 }
   [(set_attr "type" "prefetch")])

+(define_insn "prefetch_<mode>_ls2ef"
+  [(prefetch (match_operand:P 0 "register_operand" "d")
+       (match_operand 1 "const_int_operand" "n")
+       (match_operand 2 "const_int_operand" "n"))]
+  "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
+{
+  if(TARGET_LOONGSON_2EF)
+  /*Loongson 2[ef] use load to $0 to perform prefetching*/
+    return "ld\t$0,0(%0)";
+  gcc_unreachable();
+}
+  [(set_attr "type" "prefetch")])
+
 (define_insn "*prefetch_indexed_<mode>"
   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
                     (match_operand:P 1 "register_operand" "d"))
             (match_operand 2 "const_int_operand" "n")
             (match_operand 3 "const_int_operand" "n"))]
-  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
&&!TARGET_LOONGSON_2EF"
 {
   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
   return "prefx\t%2,%1(%0)";
 }
   [(set_attr "type" "prefetchx")])

+(define_split
+  [(prefetch (plus:P (match_operand:P 0 "register_operand" "")
+                    (match_operand:P 1 "register_operand" ""))
+            (match_operand 2 "const_int_operand" "")
+            (match_operand 3 "const_int_operand" ""))]
+  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT &&
TARGET_LOONGSON_2EF"
+  [(set (match_operand:P 4 "register_operand" "=d")
+       (plus:P
+               (match_dup 0)
+               (match_dup 1)))
+   (prefetch (match_dup 4)
+       (match_dup 2)
+       (match_dup 3))]
+)
+
+
 (define_insn "nop"
   [(const_int 0)]
   ""
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c      (版本 137685)
+++ gcc/config/mips/mips.c      (工作副本)
@@ -2,7 +2,7 @@
    Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
-   Contributed by A. Lichnewsky, lich@inria.inria.fr.
+//    Contributed by A. Lichnewsky, lich@inria.inria.fr.
    Changes by Michael Meissner, meissner@osf.org.
    64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
    Brendan Eich, brendan@microunity.com.
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h      (版本 137685)
+++ gcc/config/mips/mips.h      (工作副本)
@@ -275,6 +275,7 @@
 #define TARGET_LOONGSON_VECTORS            (TARGET_HARD_FLOAT_ABI
         \
                                     && TARGET_LOONGSON_2EF)

+
 /* True if the pre-reload scheduler should try to create chains of
    multiply-add or multiply-subtract instructions.  For example,
    suppose we have:
@@ -865,8 +866,9 @@
 #define ISA_HAS_PREFETCH       ((ISA_MIPS4                             \
                                  || ISA_MIPS32                         \
                                  || ISA_MIPS32R2                       \
-                                 || ISA_MIPS64)                        \
-                                && !TARGET_MIPS16)
+                                 || ISA_MIPS64                         \
+                                 || TARGET_LOONGSON_2EF)               \
+                                && !TARGET_MIPS16)

 /* ISA has data indexed prefetch instructions.  This controls use of
    'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT.
@@ -874,7 +876,8 @@
    enabled.)  */
 #define ISA_HAS_PREFETCHX      ((ISA_MIPS4                             \
                                  || ISA_MIPS32R2                       \
-                                 || ISA_MIPS64)                        \
+                                 || ISA_MIPS64                         \
+                                 || TARGET_LOONGSON_2EF)               \
                                 && !TARGET_MIPS16)

 /* True if trunc.w.s and trunc.w.d are real (not synthetic)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: loongson_new_insn_and_prefetch.patch.gz
Type: application/x-gzip
Size: 2826 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080721/97127f73/attachment.bin>


More information about the Gcc-patches mailing list