aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arc/arc.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arc/arc.md')
-rw-r--r--gcc/config/arc/arc.md252
1 files changed, 165 insertions, 87 deletions
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 9e73d02..08e6a99 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -104,35 +104,66 @@
;; GOTBASE.(Referenced as @GOTOFF)
;; ----------------------------------------------------------------------------
+(define_c_enum "unspec" [
+ DUMMY_0
+ DUMMY_1
+ DUMMY_2
+ ARC_UNSPEC_PLT
+ ARC_UNSPEC_GOT
+ ARC_UNSPEC_GOTOFF
+ UNSPEC_ARC_NORM
+ UNSPEC_ARC_NORMW
+ UNSPEC_ARC_SWAP
+ UNSPEC_ARC_DIVAW
+ UNSPEC_ARC_DIRECT
+ UNSPEC_ARC_LP
+ UNSPEC_ARC_CASESI
+ UNSPEC_ARC_FFS
+ UNSPEC_ARC_FLS
+ UNSPEC_ARC_MEMBAR
+ UNSPEC_ARC_DMACH
+ UNSPEC_ARC_DMACHU
+ UNSPEC_ARC_DMACWH
+ UNSPEC_ARC_DMACWHU
+ UNSPEC_ARC_QMACH
+ UNSPEC_ARC_QMACHU
+ UNSPEC_ARC_QMPYH
+ UNSPEC_ARC_QMPYHU
+ UNSPEC_ARC_VMAC2H
+ UNSPEC_ARC_VMAC2HU
+ UNSPEC_ARC_VMPY2H
+ UNSPEC_ARC_VMPY2HU
+ ])
+
+(define_c_enum "vunspec" [
+ VUNSPEC_ARC_RTIE
+ VUNSPEC_ARC_SYNC
+ VUNSPEC_ARC_BRK
+ VUNSPEC_ARC_FLAG
+ VUNSPEC_ARC_SLEEP
+ VUNSPEC_ARC_SWI
+ VUNSPEC_ARC_CORE_READ
+ VUNSPEC_ARC_CORE_WRITE
+ VUNSPEC_ARC_LR
+ VUNSPEC_ARC_SR
+ VUNSPEC_ARC_TRAP_S
+ VUNSPEC_ARC_UNIMP_S
+ VUNSPEC_ARC_KFLAG
+ VUNSPEC_ARC_CLRI
+ VUNSPEC_ARC_SETI
+ VUNSPEC_ARC_NOP
+ VUNSPEC_ARC_STACK_IRQ
+ VUNSPEC_ARC_DEXCL
+ VUNSPEC_ARC_DEXCL_NORES
+ VUNSPEC_ARC_LR_HIGH
+ VUNSPEC_ARC_EX
+ VUNSPEC_ARC_CAS
+ VUNSPEC_ARC_SC
+ VUNSPEC_ARC_LL
+ ])
(define_constants
- [(UNSPEC_SWAP 13) ; swap generation through builtins. candidate for scheduling
- (UNSPEC_MUL64 14) ; mul64 generation through builtins. candidate for scheduling
- (UNSPEC_MULU64 15) ; mulu64 generation through builtins. candidate for scheduling
- (UNSPEC_DIVAW 16) ; divaw generation through builtins. candidate for scheduling
- (UNSPEC_DIRECT 17)
- (UNSPEC_PROF 18) ; profile callgraph counter
- (UNSPEC_LP 19) ; to set LP_END
- (UNSPEC_CASESI 20)
- (VUNSPEC_RTIE 17) ; blockage insn for rtie generation
- (VUNSPEC_SYNC 18) ; blockage insn for sync generation
- (VUNSPEC_BRK 19) ; blockage insn for brk generation
- (VUNSPEC_FLAG 20) ; blockage insn for flag generation
- (VUNSPEC_SLEEP 21) ; blockage insn for sleep generation
- (VUNSPEC_SWI 22) ; blockage insn for swi generation
- (VUNSPEC_CORE_READ 23) ; blockage insn for reading a core register
- (VUNSPEC_CORE_WRITE 24) ; blockage insn for writing to a core register
- (VUNSPEC_LR 25) ; blockage insn for reading an auxiliary register
- (VUNSPEC_SR 26) ; blockage insn for writing to an auxiliary register
- (VUNSPEC_TRAP_S 27) ; blockage insn for trap_s generation
- (VUNSPEC_UNIMP_S 28) ; blockage insn for unimp_s generation
- (VUNSPEC_NOP 29) ; volatile NOP
-
- (UNSPEC_ARC_MEMBAR 30)
- (VUNSPEC_ARC_CAS 31)
- (VUNSPEC_ARC_LL 32)
- (VUNSPEC_ARC_SC 33)
- (VUNSPEC_ARC_EX 34)
+ [(UNSPEC_PROF 18) ; profile callgraph counter
(R0_REG 0)
(R1_REG 1)
@@ -145,10 +176,6 @@
(RETURN_ADDR_REGNUM 31)
(MUL64_OUT_REG 58)
- (VUNSPEC_DEXCL 32) ; blockage insn for reading an auxiliary register without LR support
- (VUNSPEC_DEXCL_NORES 33) ; blockage insn for reading an auxiliary register without LR support
- (VUNSPEC_LR_HIGH 34) ; blockage insn for reading an auxiliary register
-
(LP_COUNT 60)
(CC_REG 61)
(LP_START 144)
@@ -716,7 +743,7 @@
(define_insn "store_direct"
[(set (match_operand:SI 0 "move_dest_operand" "=m")
(unspec:SI [(match_operand:SI 1 "register_operand" "c")]
- UNSPEC_DIRECT))]
+ UNSPEC_ARC_DIRECT))]
""
"st%U0 %1,%0\;st%U0.di %1,%0"
[(set_attr "type" "store")])
@@ -1083,10 +1110,10 @@
; dexcl2 r0, r1, r0
(set (match_dup 4) ; aka r0result
; aka DF, r1, r0
- (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL ))
+ (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL ))
; Generate the second, which makes sure operand5 and operand4 values
; are put back in the Dx register properly.
- (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_DEXCL_NORES )
+ (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL_NORES )
; Note: we cannot use a (clobber (match_scratch)) here because
; the combine pass will end up replacing uses of it with 0
@@ -3646,7 +3673,7 @@
(pc)))
(set (match_dup 6)
(unspec:SI [(match_operand 3 "" "")
- (match_dup 5) (match_dup 7)] UNSPEC_CASESI))
+ (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
(parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
""
"
@@ -3684,7 +3711,7 @@
[(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
(unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
(match_operand:SI 2 "register_operand" "Rcq,c,c")
- (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))]
+ (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
""
"*
{
@@ -3749,7 +3776,7 @@
(define_insn "casesi_compact_jump"
[(set (pc)
(unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
- UNSPEC_CASESI))
+ UNSPEC_ARC_CASESI))
(use (label_ref (match_operand 1 "" "")))
(clobber (match_scratch:SI 2 "=q,0"))]
"TARGET_COMPACT_CASESI"
@@ -4000,7 +4027,7 @@
(set_attr "length" "2")])
(define_insn "nopv"
- [(unspec_volatile [(const_int 0)] VUNSPEC_NOP)]
+ [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
""
"nop%?"
[(set_attr "type" "misc")
@@ -4245,7 +4272,7 @@
(define_insn "swap"
[(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
(unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
- UNSPEC_SWAP))]
+ UNSPEC_ARC_SWAP))]
"TARGET_SWAP"
"@
swap \t%0, %1
@@ -4254,41 +4281,11 @@
[(set_attr "length" "4,8,4")
(set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
-;; FIXME: an intrinsic for multiply is daft. Can we remove this?
-(define_insn "mul64"
- [(unspec [(match_operand:SI 0 "general_operand" "%q,r,r,r")
- (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
- UNSPEC_MUL64)]
- "TARGET_MUL64_SET"
- "@
- mul64%? \t0, %0, %1%&
- mul64%? \t0, %0, %1
- mul64 \t0, %0, %1
- mul64%? \t0, %0, %S1"
- [(set_attr "length" "2,4,4,8")
- (set_attr "iscompact" "true,false,false,false")
- (set_attr "type" "binary,binary,binary,binary")
- (set_attr "cond" "canuse,canuse, nocond, canuse")])
-
-(define_insn "mulu64"
- [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
- (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
- UNSPEC_MULU64)]
- "TARGET_MUL64_SET"
- "@
- mulu64%? \t0, %0, %1
- mulu64 \t0, %0, %1
- mulu64 \t0, %0, %1
- mulu64%? \t0, %0, %S1"
- [(set_attr "length" "4,4,4,8")
- (set_attr "type" "binary,binary,binary,binary")
- (set_attr "cond" "canuse,nocond,nocond,canuse")])
-
(define_insn "divaw"
[(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
(unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
(match_operand:SI 2 "general_operand" "r,r,Cal"))]
- UNSPEC_DIVAW))]
+ UNSPEC_ARC_DIVAW))]
"TARGET_ARC700 || TARGET_EA_SET"
"@
divaw \t%0, %1, %2
@@ -4299,7 +4296,7 @@
(define_insn "flag"
[(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
- VUNSPEC_FLAG)]
+ VUNSPEC_ARC_FLAG)]
""
"@
flag%? %0
@@ -4312,7 +4309,7 @@
(define_insn "brk"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_BRK)]
+ VUNSPEC_ARC_BRK)]
""
"brk"
[(set_attr "length" "4")
@@ -4320,7 +4317,7 @@
(define_insn "rtie"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_RTIE)]
+ VUNSPEC_ARC_RTIE)]
""
"rtie"
[(set_attr "length" "4")
@@ -4329,7 +4326,7 @@
(define_insn "sync"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_SYNC)]
+ VUNSPEC_ARC_SYNC)]
""
"sync"
[(set_attr "length" "4")
@@ -4337,7 +4334,7 @@
(define_insn "swi"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_SWI)]
+ VUNSPEC_ARC_SWI)]
""
"*
{
@@ -4352,7 +4349,7 @@
(define_insn "sleep"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
- VUNSPEC_SLEEP)]
+ VUNSPEC_ARC_SLEEP)]
"check_if_valid_sleep_operand(operands,0)"
"sleep %0"
[(set_attr "length" "4")
@@ -4361,7 +4358,7 @@
(define_insn "core_read"
[(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
(unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
- VUNSPEC_CORE_READ))]
+ VUNSPEC_ARC_CORE_READ))]
""
"*
if (check_if_valid_regno_const (operands, 1))
@@ -4374,7 +4371,7 @@
(define_insn "core_write"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
(match_operand:SI 1 "general_operand" "Hn,!r")]
- VUNSPEC_CORE_WRITE)]
+ VUNSPEC_ARC_CORE_WRITE)]
""
"*
if (check_if_valid_regno_const (operands, 1))
@@ -4387,7 +4384,7 @@
(define_insn "lr"
[(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
(unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
- VUNSPEC_LR))]
+ VUNSPEC_ARC_LR))]
""
"lr\t%0, [%1]"
[(set_attr "length" "4,8,4,8")
@@ -4396,7 +4393,7 @@
(define_insn "sr"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
(match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
- VUNSPEC_SR)]
+ VUNSPEC_ARC_SR)]
""
"sr\t%S0, [%1]"
[(set_attr "length" "8,4,8,4")
@@ -4404,8 +4401,8 @@
(define_insn "trap_s"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
- VUNSPEC_TRAP_S)]
- "TARGET_ARC700"
+ VUNSPEC_ARC_TRAP_S)]
+ "!TARGET_ARC600_FAMILY"
{
if (which_alternative == 0)
{
@@ -4423,8 +4420,8 @@
(define_insn "unimp_s"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_UNIMP_S)]
- "TARGET_ARC700"
+ VUNSPEC_ARC_UNIMP_S)]
+ "!TARGET_ARC600_FAMILY"
"unimp_s"
[(set_attr "length" "4")
(set_attr "type" "misc")])
@@ -4867,7 +4864,7 @@
; hoist the SETs.
;(define_insn "doloop_begin_i"
; [(set (reg:SI LP_START) (pc))
-; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_LP))
+; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_ARC_LP))
; (use (match_operand 0 "const_int_operand" "n"))]
; ""
; "lp .L__GCC__LP%0"
@@ -4881,7 +4878,7 @@
;
; N in XVECEXP PATTERN (lp, 0 N)
; V rtl purpose
-; 0 unspec UNSPEC_LP identify pattern
+; 0 unspec UNSPEC_ARC_LP identify pattern
; 1 clobber LP_START show LP_START is set
; 2 clobber LP_END show LP_END is set
; 3 use operand0 loop count pseudo register
@@ -4896,7 +4893,7 @@
; There is no point is reloading this insn - then lp_count would still not
; be available for the loop end.
(define_insn "doloop_begin_i"
- [(unspec:SI [(pc)] UNSPEC_LP)
+ [(unspec:SI [(pc)] UNSPEC_ARC_LP)
(clobber (reg:SI LP_START))
(clobber (reg:SI LP_END))
(use (match_operand:SI 0 "register_operand" "l,l,????*X"))
@@ -5533,6 +5530,87 @@
(set_attr "predicable" "yes,no,no,yes,no")
(set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
+(define_insn "kflag"
+ [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
+ VUNSPEC_ARC_KFLAG)]
+ "TARGET_V2"
+ "@
+ kflag%? %0
+ kflag %0
+ kflag%? %S0"
+ [(set_attr "length" "4,4,8")
+ (set_attr "type" "misc,misc,misc")
+ (set_attr "predicable" "yes,no,yes")
+ (set_attr "cond" "clob,clob,clob")])
+
+(define_insn "clri"
+ [(set (match_operand:SI 0 "dest_reg_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
+ VUNSPEC_ARC_CLRI))]
+ "TARGET_V2"
+ "clri %0"
+ [(set_attr "length" "4")
+ (set_attr "type" "misc")])
+
+(define_insn "ffs"
+ [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+ (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
+ UNSPEC_ARC_FFS))]
+ "TARGET_NORM && TARGET_V2"
+ "@
+ ffs \t%0, %1
+ ffs \t%0, %S1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "two_cycle_core,two_cycle_core")])
+
+(define_insn "ffs_f"
+ [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+ (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
+ UNSPEC_ARC_FFS))
+ (set (reg:CC_ZN CC_REG)
+ (compare:CC_ZN (match_dup 1) (const_int 0)))]
+ "TARGET_NORM && TARGET_V2"
+ "@
+ ffs.f\t%0, %1
+ ffs.f\t%0, %S1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "two_cycle_core,two_cycle_core")])
+
+(define_expand "ffssi2"
+ [(parallel [(set (match_dup 2)
+ (unspec:SI [(match_operand:SI 1 "register_operand" "")]
+ UNSPEC_ARC_FFS))
+ (set (reg:CC_ZN CC_REG)
+ (compare:CC_ZN (match_dup 1) (const_int 0)))])
+ (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
+ (set (match_operand:SI 0 "dest_reg_operand" "")
+ (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
+ (const_int 0)
+ (match_dup 2)))]
+ "TARGET_NORM && TARGET_V2"
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ })
+
+(define_insn "fls"
+ [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+ (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
+ UNSPEC_ARC_FLS))]
+ "TARGET_NORM && TARGET_V2"
+ "@
+ fls \t%0, %1
+ fls \t%0, %S1"
+ [(set_attr "length" "4,8")
+ (set_attr "type" "two_cycle_core,two_cycle_core")])
+
+(define_insn "seti"
+ [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
+ VUNSPEC_ARC_SETI)]
+ "TARGET_V2"
+ "seti %0"
+ [(set_attr "length" "4")
+ (set_attr "type" "misc")])
+
;; include the arc-FPX instructions
(include "fpx.md")