diff options
author | vp <vp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-27 10:50:26 +0000 |
---|---|---|
committer | vp <vp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-27 10:50:26 +0000 |
commit | 56741832c68d442e021ed0491cb3a9d5c8f1f697 (patch) | |
tree | df24a9554d92f8cbb0f4fd25a81861117939c839 /gcc/config | |
parent | 71fa3334cbf5c0de7bb3d5bec266f29c64e66d23 (diff) | |
download | gcc-56741832c68d442e021ed0491cb3a9d5c8f1f697.tar.gz |
gcc/
2013-08-27 Vidya Praveen <vidyapraveen@arm.com>
* config/aarch64/aarch64.md (unspec): Add UNSPEC_SISD_SSHL,
UNSPEC_SISD_USHL, UNSPEC_USHL_2S, UNSPEC_SSHL_2S, UNSPEC_SISD_NEG.
(<optab><mode>3_insn): Remove.
(aarch64_ashl_sisd_or_int_<mode>3): New Pattern.
(aarch64_lshr_sisd_or_int_<mode>3): Likewise.
(aarch64_ashr_sisd_or_int_<mode>3): Likewise.
(define_split for aarch64_lshr_sisd_or_int_di3): Likewise.
(define_split for aarch64_lshr_sisd_or_int_si3): Likewise.
(define_split for aarch64_ashr_sisd_or_int_di3): Likewise.
(define_split for aarch64_ashr_sisd_or_int_si3): Likewise.
(aarch64_sisd_ushl, aarch64_sisd_sshl): Likewise.
(aarch64_ushl_2s, aarch64_sshl_2s, aarch64_sisd_neg_qi): Likewise.
(ror<mode>3_insn): Likewise.
* config/aarch64/predicates.md (aarch64_simd_register): New.
gcc/testsuite/
2013-08-27 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/scalar_shift_1.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202020 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 184 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 5 |
2 files changed, 184 insertions, 5 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 5312a796ed9..47532fca2c5 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -88,11 +88,16 @@ UNSPEC_NOP UNSPEC_PRLG_STK UNSPEC_RBIT + UNSPEC_SISD_NEG + UNSPEC_SISD_SSHL + UNSPEC_SISD_USHL + UNSPEC_SSHL_2S UNSPEC_ST2 UNSPEC_ST3 UNSPEC_ST4 UNSPEC_TLS UNSPEC_TLSDESC + UNSPEC_USHL_2S UNSPEC_VSTRUCTDUMMY ]) @@ -3183,13 +3188,182 @@ } ) -(define_insn "*<optab><mode>3_insn" +;; Logical left shift using SISD or Integer instruction +(define_insn "*aarch64_ashl_sisd_or_int_<mode>3" + [(set (match_operand:GPI 0 "register_operand" "=w,w,r") + (ashift:GPI + (match_operand:GPI 1 "register_operand" "w,w,r") + (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))] + "" + "@ + shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2 + ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas> + lsl\t%<w>0, %<w>1, %<w>2" + [(set_attr "simd" "yes,yes,no") + (set_attr "simd_type" "simd_shift_imm,simd_shift,*") + (set_attr "simd_mode" "<MODE>,<MODE>,*") + (set_attr "v8type" "*,*,shift") + (set_attr "type" "*,*,shift") + (set_attr "mode" "*,*,<MODE>")] +) + +;; Logical right shift using SISD or Integer instruction +(define_insn "*aarch64_lshr_sisd_or_int_<mode>3" + [(set (match_operand:GPI 0 "register_operand" "=w,w,r") + (lshiftrt:GPI + (match_operand:GPI 1 "register_operand" "w,w,r") + (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))] + "" + "@ + ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 + # + lsr\t%<w>0, %<w>1, %<w>2" + [(set_attr "simd" "yes,yes,no") + (set_attr "simd_type" "simd_shift_imm,simd_shift,*") + (set_attr "simd_mode" "<MODE>,<MODE>,*") + (set_attr "v8type" "*,*,shift") + (set_attr "type" "*,*,shift") + (set_attr "mode" "*,*,<MODE>")] +) + +(define_split + [(set (match_operand:DI 0 "aarch64_simd_register") + (lshiftrt:DI + (match_operand:DI 1 "aarch64_simd_register") + (match_operand:QI 2 "aarch64_simd_register")))] + "TARGET_SIMD && reload_completed" + [(set (match_dup 2) + (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) + (set (match_dup 0) + (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))] + "" +) + +(define_split + [(set (match_operand:SI 0 "aarch64_simd_register") + (lshiftrt:SI + (match_operand:SI 1 "aarch64_simd_register") + (match_operand:QI 2 "aarch64_simd_register")))] + "TARGET_SIMD && reload_completed" + [(set (match_dup 2) + (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) + (set (match_dup 0) + (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))] + "" +) + +;; Arithmetic right shift using SISD or Integer instruction +(define_insn "*aarch64_ashr_sisd_or_int_<mode>3" + [(set (match_operand:GPI 0 "register_operand" "=w,w,r") + (ashiftrt:GPI + (match_operand:GPI 1 "register_operand" "w,w,r") + (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))] + "" + "@ + sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 + # + asr\t%<w>0, %<w>1, %<w>2" + [(set_attr "simd" "yes,yes,no") + (set_attr "simd_type" "simd_shift_imm,simd_shift,*") + (set_attr "simd_mode" "<MODE>,<MODE>,*") + (set_attr "v8type" "*,*,shift") + (set_attr "type" "*,*,shift") + (set_attr "mode" "*,*,<MODE>")] +) + +(define_split + [(set (match_operand:DI 0 "aarch64_simd_register") + (ashiftrt:DI + (match_operand:DI 1 "aarch64_simd_register") + (match_operand:QI 2 "aarch64_simd_register")))] + "TARGET_SIMD && reload_completed" + [(set (match_dup 2) + (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) + (set (match_dup 0) + (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))] + "" +) + +(define_split + [(set (match_operand:SI 0 "aarch64_simd_register") + (ashiftrt:SI + (match_operand:SI 1 "aarch64_simd_register") + (match_operand:QI 2 "aarch64_simd_register")))] + "TARGET_SIMD && reload_completed" + [(set (match_dup 2) + (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG)) + (set (match_dup 0) + (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))] + "" +) + +(define_insn "*aarch64_sisd_ushl" + [(set (match_operand:DI 0 "register_operand" "=w") + (unspec:DI [(match_operand:DI 1 "register_operand" "w") + (match_operand:QI 2 "register_operand" "w")] + UNSPEC_SISD_USHL))] + "TARGET_SIMD" + "ushl\t%d0, %d1, %d2" + [(set_attr "simd" "yes") + (set_attr "simd_type" "simd_shift") + (set_attr "simd_mode" "DI")] +) + +(define_insn "*aarch64_ushl_2s" + [(set (match_operand:SI 0 "register_operand" "=w") + (unspec:SI [(match_operand:SI 1 "register_operand" "w") + (match_operand:QI 2 "register_operand" "w")] + UNSPEC_USHL_2S))] + "TARGET_SIMD" + "ushl\t%0.2s, %1.2s, %2.2s" + [(set_attr "simd" "yes") + (set_attr "simd_type" "simd_shift") + (set_attr "simd_mode" "DI")] +) + +(define_insn "*aarch64_sisd_sshl" + [(set (match_operand:DI 0 "register_operand" "=w") + (unspec:DI [(match_operand:DI 1 "register_operand" "w") + (match_operand:QI 2 "register_operand" "w")] + UNSPEC_SISD_SSHL))] + "TARGET_SIMD" + "sshl\t%d0, %d1, %d2" + [(set_attr "simd" "yes") + (set_attr "simd_type" "simd_shift") + (set_attr "simd_mode" "DI")] +) + +(define_insn "*aarch64_sshl_2s" + [(set (match_operand:SI 0 "register_operand" "=w") + (unspec:SI [(match_operand:SI 1 "register_operand" "w") + (match_operand:QI 2 "register_operand" "w")] + UNSPEC_SSHL_2S))] + "TARGET_SIMD" + "sshl\t%0.2s, %1.2s, %2.2s" + [(set_attr "simd" "yes") + (set_attr "simd_type" "simd_shift") + (set_attr "simd_mode" "DI")] +) + +(define_insn "*aarch64_sisd_neg_qi" + [(set (match_operand:QI 0 "register_operand" "=w") + (unspec:QI [(match_operand:QI 1 "register_operand" "w")] + UNSPEC_SISD_NEG))] + "TARGET_SIMD" + "neg\t%d0, %d1" + [(set_attr "simd" "yes") + (set_attr "simd_type" "simd_negabs") + (set_attr "simd_mode" "QI")] +) + +;; Rotate right +(define_insn "*ror<mode>3_insn" [(set (match_operand:GPI 0 "register_operand" "=r") - (SHIFT:GPI - (match_operand:GPI 1 "register_operand" "r") - (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))] + (rotatert:GPI + (match_operand:GPI 1 "register_operand" "r") + (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))] "" - "<shift>\\t%<w>0, %<w>1, %<w>2" + "ror\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "shift") (set_attr "type" "shift") (set_attr "mode" "<MODE>")] diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 3e2b6b34357..dbc90826665 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -26,6 +26,11 @@ && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))) ) +(define_predicate "aarch64_simd_register" + (and (match_code "reg") + (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS") + (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS")))) + (define_predicate "aarch64_reg_or_zero" (and (match_code "reg,subreg,const_int") (ior (match_operand 0 "register_operand") |