summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorvp <vp@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-27 10:50:26 +0000
committervp <vp@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-27 10:50:26 +0000
commit56741832c68d442e021ed0491cb3a9d5c8f1f697 (patch)
treedf24a9554d92f8cbb0f4fd25a81861117939c839 /gcc/config
parent71fa3334cbf5c0de7bb3d5bec266f29c64e66d23 (diff)
downloadgcc-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.md184
-rw-r--r--gcc/config/aarch64/predicates.md5
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")