From: Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
To: <gcc-patches@gcc.gnu.org>
Cc: <Claudiu.Zissulescu@synopsys.com>, <Francois.Bedard@synopsys.com>,
<andrew.burgess@embecosm.com>
Subject: [PATCH 3/3] [ARC] Add support for advanced mpy/mac instructions.
Date: Tue, 25 Apr 2017 13:21:00 -0000 [thread overview]
Message-ID: <1493125424-7298-4-git-send-email-claziss@synopsys.com> (raw)
In-Reply-To: <1493125424-7298-1-git-send-email-claziss@synopsys.com>
Add support for MAC and DMPY instructions. ARCv2 Only.
gcc/
2016-12-08 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.c (arc_conditional_register_usage): Handle ACCL,
ACCH registers.
* config/arc/arc.md (mulsidi3): Use advanced mpy instructions when
available.
(umulsidi3): Likewise.
(mulsidi3_700): Disable this pattern when we have advanced mpy
instructions.
(umulsidi3_700): Likewise.
(maddsidi4): New pattern.
(macd, mac, mac_r, umaddsidi4, macdu, macu, macu_r): Likewise.
(mpyd_arcv2hs, mpyd_imm_arcv2hs, mpydu_arcv2hs): Likewise.
(mpydu_imm_arcv2hs): Likewise.
* config/arc/predicates.md (accl_operand): New predicate.
---
gcc/config/arc/arc.c | 5 +-
gcc/config/arc/arc.md | 266 ++++++++++++++++++++++++++++++++++++++++++-
gcc/config/arc/predicates.md | 5 +
3 files changed, 272 insertions(+), 4 deletions(-)
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 170b8dd..238244b 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1789,8 +1789,9 @@ arc_conditional_register_usage (void)
arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
/*ARCV2 Accumulator. */
- if (TARGET_V2
- && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
+ if ((TARGET_V2
+ && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
+ || TARGET_PLUS_DMPY)
{
arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index ffab390..db5867c 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -2157,6 +2157,18 @@
"TARGET_ANY_MPY"
"
{
+ if (TARGET_PLUS_MACD)
+ {
+ if (CONST_INT_P (operands[2]))
+ {
+ emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
+ }
+ else
+ {
+ emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
+ }
+ DONE;
+ }
if (TARGET_MPY)
{
operands[2] = force_reg (SImode, operands[2]);
@@ -2237,7 +2249,7 @@
[(set (match_operand:DI 0 "register_operand" "=&r")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
(sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
- "TARGET_MPY"
+ "TARGET_MPY && !TARGET_PLUS_MACD"
"#"
"&& reload_completed"
[(const_int 0)]
@@ -2390,6 +2402,18 @@
(zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
""
{
+ if (TARGET_PLUS_MACD)
+ {
+ if (CONST_INT_P (operands[2]))
+ {
+ emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
+ }
+ else
+ {
+ emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
+ }
+ DONE;
+ }
if (TARGET_MPY)
{
operands[2] = force_reg (SImode, operands[2]);
@@ -2480,7 +2504,7 @@
[(set (match_operand:DI 0 "dest_reg_operand" "=&r")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
(zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
- "TARGET_MPY"
+ "TARGET_MPY && !TARGET_PLUS_MACD"
"#"
"reload_completed"
[(const_int 0)]
@@ -6215,6 +6239,244 @@
""
[(set_attr "length" "0")])
+;; MAC and DMPY instructions
+(define_insn_and_split "maddsidi4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
+ (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
+ (match_operand:DI 3 "register_operand" "r")))]
+ "TARGET_PLUS_DMPY"
+ "#"
+ "TARGET_PLUS_DMPY && reload_completed"
+ [(const_int 0)]
+ "{
+ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
+ emit_move_insn (acc_reg, operands[3]);
+ if (TARGET_PLUS_MACD)
+ emit_insn (gen_macd (operands[0], operands[1], operands[2]));
+ else
+ {
+ emit_insn (gen_mac (operands[1], operands[2]));
+ emit_move_insn (operands[0], acc_reg);
+ }
+ DONE;
+ }"
+ [(set_attr "type" "multi")
+ (set_attr "length" "36")])
+
+(define_insn "macd"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
+ (plus:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
+ (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
+ (reg:DI ARCV2_ACC)))
+ (set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (reg:DI ARCV2_ACC)))]
+ "TARGET_PLUS_MACD"
+ "macd %0,%1,%2"
+ [(set_attr "length" "4,4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no,no")
+ (set_attr "cond" "canuse,nocond,nocond")])
+
+(define_insn "mac"
+ [(set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
+ (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
+ (reg:DI ARCV2_ACC)))]
+ "TARGET_PLUS_DMPY"
+ "mac 0,%0,%1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "no")
+ (set_attr "cond" "nocond")])
+
+(define_peephole2
+ [(set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
+ (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
+ (reg:DI ARCV2_ACC)))
+ (set (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "accl_operand" ""))]
+ "TARGET_PLUS_DMPY"
+ [(const_int 0)]
+ {
+ emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
+ DONE;
+ })
+
+(define_insn "mac_r"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (truncate:SI
+ (plus:DI
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
+ (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
+ (reg:DI ARCV2_ACC))))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_DMPY"
+ "mac %0,%1,%2"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "no")
+ (set_attr "cond" "nocond")])
+
+(define_insn_and_split "umaddsidi4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
+ (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
+ (match_operand:DI 3 "register_operand" "r")))]
+ "TARGET_PLUS_DMPY"
+ "#"
+ "TARGET_PLUS_DMPY && reload_completed"
+ [(const_int 0)]
+ "{
+ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
+ emit_move_insn (acc_reg, operands[3]);
+ if (TARGET_PLUS_MACD)
+ emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
+ else
+ {
+ emit_insn (gen_macu (operands[1], operands[2]));
+ emit_move_insn (operands[0], acc_reg);
+ }
+ DONE;
+ }"
+ [(set_attr "type" "multi")
+ (set_attr "length" "36")])
+
+(define_insn "macdu"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
+ (plus:DI
+ (mult:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
+ (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
+ (reg:DI ARCV2_ACC)))
+ (set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (zero_extend:DI (match_dup 1))
+ (zero_extend:DI (match_dup 2)))
+ (reg:DI ARCV2_ACC)))]
+ "TARGET_PLUS_MACD"
+ "macdu %0,%1,%2"
+ [(set_attr "length" "4,4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no,no")
+ (set_attr "cond" "canuse,nocond,nocond")])
+
+(define_insn "macu"
+ [(set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
+ (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
+ (reg:DI ARCV2_ACC)))]
+ "TARGET_PLUS_DMPY"
+ "macu 0,%0,%1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "no")
+ (set_attr "cond" "nocond")])
+
+(define_peephole2
+ [(set (reg:DI ARCV2_ACC)
+ (plus:DI
+ (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
+ (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
+ (reg:DI ARCV2_ACC)))
+ (set (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "accl_operand" ""))]
+ "TARGET_PLUS_DMPY"
+ [(const_int 0)]
+ {
+ emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
+ DONE;
+ })
+
+(define_insn "macu_r"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (truncate:SI
+ (plus:DI
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
+ (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
+ (reg:DI ARCV2_ACC))))
+ (clobber (reg:DI ARCV2_ACC))]
+ "TARGET_PLUS_DMPY"
+ "macu %0,%1,%2"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "no")
+ (set_attr "cond" "nocond")])
+
+(define_insn "mpyd_arcv2hs"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
+ (set (reg:DI ARCV2_ACC)
+ (mult:DI
+ (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2))))]
+ "TARGET_PLUS_MACD"
+ "mpyd%? %0,%1,%2"
+ [(set_attr "length" "4,4")
+ (set_attr "iscompact" "false")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "mpyd_imm_arcv2hs"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
+ (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
+ (set (reg:DI ARCV2_ACC)
+ (mult:DI (sign_extend:DI (match_dup 1))
+ (match_dup 2)))]
+ "TARGET_PLUS_MACD"
+ "mpyd%? %0,%1,%2"
+ [(set_attr "length" "4,4,4,8,8")
+ (set_attr "iscompact" "false")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no,no,yes,no")
+ (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
+
+(define_insn "mpydu_arcv2hs"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
+ (set (reg:DI ARCV2_ACC)
+ (mult:DI (zero_extend:DI (match_dup 1))
+ (zero_extend:DI (match_dup 2))))]
+ "TARGET_PLUS_MACD"
+ "mpydu%? %0,%1,%2"
+ [(set_attr "length" "4,4")
+ (set_attr "iscompact" "false")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no")
+ (set_attr "cond" "canuse,nocond")])
+
+(define_insn "mpydu_imm_arcv2hs"
+ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
+ (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
+ (set (reg:DI ARCV2_ACC)
+ (mult:DI (zero_extend:DI (match_dup 1))
+ (match_dup 2)))]
+ "TARGET_PLUS_MACD"
+ "mpydu%? %0,%1,%2"
+ [(set_attr "length" "4,4,4,8,8")
+ (set_attr "iscompact" "false")
+ (set_attr "type" "multi")
+ (set_attr "predicable" "yes,no,no,yes,no")
+ (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
+
;; include the arc-FPX instructions
(include "fpx.md")
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index f4c2a80..7ddec91 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -697,6 +697,11 @@
(and (match_code "reg")
(match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 58 : 59)")))
+(define_predicate "accl_operand"
+ (and (match_code "reg")
+ (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 59 : 58)")
+ (match_test "TARGET_V2")))
+
; Unfortunately, we can not allow a const_int_operand before reload, because
; reload needs a non-void mode to guide it how to reload the inside of a
; {sign_}extend.
--
1.9.1
next prev parent reply other threads:[~2017-04-25 13:06 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-25 13:06 [PATCH 0/3] [ARC] New features Claudiu Zissulescu
2017-04-25 13:21 ` Claudiu Zissulescu [this message]
2017-05-08 15:10 ` [PATCH 3/3] [ARC] Add support for advanced mpy/mac instructions Andrew Burgess
2017-05-09 14:42 ` Claudiu Zissulescu
2017-04-25 13:27 ` [PATCH 2/3] [ARC] Fast interrupts support Claudiu Zissulescu
2017-04-25 15:54 ` Sandra Loosemore
2017-04-26 13:14 ` Claudiu Zissulescu
2017-04-25 13:29 ` [PATCH 1/3] [ARC] Automatic context save/restore for regular interrupts Claudiu Zissulescu
2017-04-25 15:46 ` Sandra Loosemore
2017-04-26 13:15 ` Claudiu Zissulescu
2017-05-05 11:05 ` [PATCH 0/2] [ARC] New features (updated) Claudiu Zissulescu
2017-05-05 11:05 ` [PATCH 1/2] Automatic context save/restore for regular interrupts Claudiu Zissulescu
2017-05-08 14:50 ` Andrew Burgess
2017-05-09 14:24 ` Claudiu Zissulescu
2017-05-05 11:23 ` [PATCH 2/2] Fast interrupts support Claudiu Zissulescu
2017-05-08 14:54 ` Andrew Burgess
2017-05-09 14:25 ` Claudiu Zissulescu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1493125424-7298-4-git-send-email-claziss@synopsys.com \
--to=claudiu.zissulescu@synopsys.com \
--cc=Francois.Bedard@synopsys.com \
--cc=andrew.burgess@embecosm.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).