[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