diff options
Diffstat (limited to 'gcc/config/arc/arc.md')
-rw-r--r-- | gcc/config/arc/arc.md | 252 |
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") |