aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-10-26 11:46:45 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-10-26 11:46:45 +0200
commite43451aaaf45b9d8d43f6dd2aa1ac1b51d6089ed (patch)
treec91519d05344769a0667ba605555a25ca11f993b /gcc/config
parent6c137ca0a2c514c3d8003b4a38e9b0d1cb3237b2 (diff)
downloadgcc-e43451aaaf45b9d8d43f6dd2aa1ac1b51d6089ed.zip
gcc-e43451aaaf45b9d8d43f6dd2aa1ac1b51d6089ed.tar.gz
gcc-e43451aaaf45b9d8d43f6dd2aa1ac1b51d6089ed.tar.bz2
i386.md (UNSPEC_VSIBADDR): New.
* config/i386/i386.md (UNSPEC_VSIBADDR): New. * config/i386/predicates.md (vsib_address_operand, vsib_mem_operator): New predicates. * config/i386/i386.c (ix86_print_operand_address): Handle UNSPEC_VSIBADDR addresses. * config/i386/sse.md (avx2_gathersi<mode>, avx2_gatherdi<mode>, avx2_gatherdi<mode>256): Adjust expanders to use MEM with UNSPEC_VSIBADDR address. (*avx2_gathersi<mode>, *avx2_gatherdi<mode>, *avx2_gatherdi<mode>256): Adjust insns to use MEM with UNSPEC_VSIBADDR address. * gcc.target/i386/avx2-i32gatherd-1.c: Adjust scan-assembler regex to work also with -masm=intel and additionally test the xmm vs. ymm register type combination on mask/dest and in vsib. * gcc.target/i386/avx2-i32gatherd256-1.c: Likewise. * gcc.target/i386/avx2-i32gatherd256-3.c: Likewise. * gcc.target/i386/avx2-i32gatherd-3.c: Likewise. * gcc.target/i386/avx2-i32gatherpd-1.c: Likewise. * gcc.target/i386/avx2-i32gatherpd256-1.c: Likewise. * gcc.target/i386/avx2-i32gatherpd256-3.c: Likewise. * gcc.target/i386/avx2-i32gatherpd-3.c: Likewise. * gcc.target/i386/avx2-i32gatherps-1.c: Likewise. * gcc.target/i386/avx2-i32gatherps256-1.c: Likewise. * gcc.target/i386/avx2-i32gatherps256-3.c: Likewise. * gcc.target/i386/avx2-i32gatherps-3.c: Likewise. * gcc.target/i386/avx2-i32gatherq-1.c: Likewise. * gcc.target/i386/avx2-i32gatherq256-1.c: Likewise. * gcc.target/i386/avx2-i32gatherq256-3.c: Likewise. * gcc.target/i386/avx2-i32gatherq-3.c: Likewise. * gcc.target/i386/avx2-i64gatherd-1.c: Likewise. * gcc.target/i386/avx2-i64gatherd256-1.c: Likewise. * gcc.target/i386/avx2-i64gatherd256-3.c: Likewise. * gcc.target/i386/avx2-i64gatherd-3.c: Likewise. * gcc.target/i386/avx2-i64gatherpd-1.c: Likewise. * gcc.target/i386/avx2-i64gatherpd256-1.c: Likewise. * gcc.target/i386/avx2-i64gatherpd256-3.c: Likewise. * gcc.target/i386/avx2-i64gatherpd-3.c: Likewise. * gcc.target/i386/avx2-i64gatherps-1.c: Likewise. * gcc.target/i386/avx2-i64gatherps256-1.c: Likewise. * gcc.target/i386/avx2-i64gatherps256-3.c: Likewise. * gcc.target/i386/avx2-i64gatherps-3.c: Likewise. * gcc.target/i386/avx2-i64gatherq-1.c: Likewise. * gcc.target/i386/avx2-i64gatherq256-1.c: Likewise. * gcc.target/i386/avx2-i64gatherq256-3.c: Likewise. * gcc.target/i386/avx2-i64gatherq-3.c: Likewise. From-SVN: r180520
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c23
-rw-r--r--gcc/config/i386/i386.md1
-rw-r--r--gcc/config/i386/predicates.md36
-rw-r--r--gcc/config/i386/sse.md90
4 files changed, 115 insertions, 35 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0d5063e..c6e09ae 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -14231,7 +14231,20 @@ ix86_print_operand_address (FILE *file, rtx addr)
struct ix86_address parts;
rtx base, index, disp;
int scale;
- int ok = ix86_decompose_address (addr, &parts);
+ int ok;
+ bool vsib = false;
+
+ if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
+ {
+ ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
+ gcc_assert (parts.index == NULL_RTX);
+ parts.index = XVECEXP (addr, 0, 1);
+ parts.scale = INTVAL (XVECEXP (addr, 0, 2));
+ addr = XVECEXP (addr, 0, 0);
+ vsib = true;
+ }
+ else
+ ok = ix86_decompose_address (addr, &parts);
gcc_assert (ok);
@@ -14328,8 +14341,8 @@ ix86_print_operand_address (FILE *file, rtx addr)
if (index)
{
putc (',', file);
- print_reg (index, code, file);
- if (scale != 1)
+ print_reg (index, vsib ? 0 : code, file);
+ if (scale != 1 || vsib)
fprintf (file, ",%d", scale);
}
putc (')', file);
@@ -14379,8 +14392,8 @@ ix86_print_operand_address (FILE *file, rtx addr)
if (index)
{
putc ('+', file);
- print_reg (index, code, file);
- if (scale != 1)
+ print_reg (index, vsib ? 0 : code, file);
+ if (scale != 1 || vsib)
fprintf (file, "*%d", scale);
}
putc (']', file);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 866fb05..6eb6152 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -237,6 +237,7 @@
UNSPEC_VPERMSF
UNSPEC_VPERMTI
UNSPEC_GATHER
+ UNSPEC_VSIBADDR
;; For BMI support
UNSPEC_BEXTR
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 349f5b0..48e110a 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -825,6 +825,42 @@
return parts.seg == SEG_DEFAULT;
})
+;; Return true if op if a valid base register, displacement or
+;; sum of base register and displacement for VSIB addressing.
+(define_predicate "vsib_address_operand"
+ (match_operand 0 "address_operand")
+{
+ struct ix86_address parts;
+ int ok;
+ rtx disp;
+
+ ok = ix86_decompose_address (op, &parts);
+ gcc_assert (ok);
+ if (parts.index || parts.seg != SEG_DEFAULT)
+ return false;
+
+ /* VSIB addressing doesn't support (%rip). */
+ if (parts.disp && GET_CODE (parts.disp) == CONST)
+ {
+ disp = XEXP (parts.disp, 0);
+ if (GET_CODE (disp) == PLUS)
+ disp = XEXP (disp, 0);
+ if (GET_CODE (disp) == UNSPEC)
+ switch (XINT (disp, 1))
+ {
+ case UNSPEC_GOTPCREL:
+ case UNSPEC_PCREL:
+ case UNSPEC_GOTNTPOFF:
+ return false;
+ }
+ }
+
+ return true;
+})
+
+(define_predicate "vsib_mem_operator"
+ (match_code "mem"))
+
;; Return true if the rtx is known to be at least 32 bits aligned.
(define_predicate "aligned_operand"
(match_operand 0 "general_operand")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 31c40d3..73429e4 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -12693,28 +12693,38 @@
[(parallel [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
(unspec:VEC_GATHER_MODE
[(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
- (match_operand 2 "register_operand" "")
+ (mem:<ssescalarmode>
+ (match_par_dup 7
+ [(match_operand 2 "vsib_address_operand" "")
+ (match_operand:<VEC_GATHER_MODE> 3 "register_operand" "")
+ (match_operand:SI 5 "const1248_operand " "")]))
(mem:BLK (scratch))
- (match_operand:<VEC_GATHER_MODE> 3 "register_operand" "")
- (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
- (match_operand:SI 5 "const1248_operand " "")]
+ (match_operand:VEC_GATHER_MODE 4 "register_operand" "")]
UNSPEC_GATHER))
(clobber (match_scratch:VEC_GATHER_MODE 6 ""))])]
- "TARGET_AVX2")
+ "TARGET_AVX2"
+{
+ operands[7]
+ = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, operands[2], operands[3],
+ operands[5]), UNSPEC_VSIBADDR);
+})
(define_insn "*avx2_gathersi<mode>"
[(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
(unspec:VEC_GATHER_MODE
[(match_operand:VEC_GATHER_MODE 2 "register_operand" "0")
- (match_operand:P 3 "register_operand" "r")
+ (match_operator:<ssescalarmode> 7 "vsib_mem_operator"
+ [(unspec:P
+ [(match_operand:P 3 "vsib_address_operand" "p")
+ (match_operand:<VEC_GATHER_MODE> 4 "register_operand" "x")
+ (match_operand:SI 6 "const1248_operand" "n")]
+ UNSPEC_VSIBADDR)])
(mem:BLK (scratch))
- (match_operand:<VEC_GATHER_MODE> 4 "register_operand" "x")
- (match_operand:VEC_GATHER_MODE 5 "register_operand" "1")
- (match_operand:SI 6 "const1248_operand" "n")]
+ (match_operand:VEC_GATHER_MODE 5 "register_operand" "1")]
UNSPEC_GATHER))
(clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
"TARGET_AVX2"
- "v<sseintprefix>gatherd<ssemodesuffix>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), %1}"
+ "v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
@@ -12723,28 +12733,38 @@
[(parallel [(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "")
(unspec:VEC_GATHER_MODE
[(match_operand:VEC_GATHER_MODE 1 "register_operand" "")
- (match_operand 2 "register_operand" "")
+ (mem:<ssescalarmode>
+ (match_par_dup 7
+ [(match_operand 2 "vsib_address_operand" "")
+ (match_operand:<AVXMODE48P_DI> 3 "register_operand" "")
+ (match_operand:SI 5 "const1248_operand " "")]))
(mem:BLK (scratch))
- (match_operand:<AVXMODE48P_DI> 3 "register_operand" "")
- (match_operand:VEC_GATHER_MODE 4 "register_operand" "")
- (match_operand:SI 5 "const1248_operand " "")]
+ (match_operand:VEC_GATHER_MODE 4 "register_operand" "")]
UNSPEC_GATHER))
(clobber (match_scratch:VEC_GATHER_MODE 6 ""))])]
- "TARGET_AVX2")
+ "TARGET_AVX2"
+{
+ operands[7]
+ = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, operands[2], operands[3],
+ operands[5]), UNSPEC_VSIBADDR);
+})
(define_insn "*avx2_gatherdi<mode>"
[(set (match_operand:AVXMODE48P_DI 0 "register_operand" "=&x")
(unspec:AVXMODE48P_DI
[(match_operand:AVXMODE48P_DI 2 "register_operand" "0")
- (match_operand:P 3 "register_operand" "r")
+ (match_operator:<ssescalarmode> 7 "vsib_mem_operator"
+ [(unspec:P
+ [(match_operand:P 3 "vsib_address_operand" "p")
+ (match_operand:<AVXMODE48P_DI> 4 "register_operand" "x")
+ (match_operand:SI 6 "const1248_operand" "n")]
+ UNSPEC_VSIBADDR)])
(mem:BLK (scratch))
- (match_operand:<AVXMODE48P_DI> 4 "register_operand" "x")
- (match_operand:AVXMODE48P_DI 5 "register_operand" "1")
- (match_operand:SI 6 "const1248_operand" "n")]
+ (match_operand:AVXMODE48P_DI 5 "register_operand" "1")]
UNSPEC_GATHER))
(clobber (match_scratch:AVXMODE48P_DI 1 "=&x"))]
"TARGET_AVX2"
- "v<sseintprefix>gatherq<ssemodesuffix>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), %1}"
+ "v<sseintprefix>gatherq<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
@@ -12755,28 +12775,38 @@
[(parallel [(set (match_operand:VI4F_128 0 "register_operand" "")
(unspec:VI4F_128
[(match_operand:VI4F_128 1 "register_operand" "")
- (match_operand 2 "register_operand" "")
+ (mem:<ssescalarmode>
+ (match_par_dup 7
+ [(match_operand 2 "vsib_address_operand" "")
+ (match_operand:V4DI 3 "register_operand" "")
+ (match_operand:SI 5 "const1248_operand " "")]))
(mem:BLK (scratch))
- (match_operand:V4DI 3 "register_operand" "")
- (match_operand:VI4F_128 4 "register_operand" "")
- (match_operand:SI 5 "const1248_operand " "")]
+ (match_operand:VI4F_128 4 "register_operand" "")]
UNSPEC_GATHER))
(clobber (match_scratch:VI4F_128 6 ""))])]
- "TARGET_AVX2")
+ "TARGET_AVX2"
+{
+ operands[7]
+ = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, operands[2], operands[3],
+ operands[5]), UNSPEC_VSIBADDR);
+})
(define_insn "*avx2_gatherdi<mode>256"
[(set (match_operand:VI4F_128 0 "register_operand" "=x")
(unspec:VI4F_128
[(match_operand:VI4F_128 2 "register_operand" "0")
- (match_operand:P 3 "register_operand" "r")
+ (match_operator:<ssescalarmode> 7 "vsib_mem_operator"
+ [(unspec:P
+ [(match_operand:P 3 "vsib_address_operand" "p")
+ (match_operand:V4DI 4 "register_operand" "x")
+ (match_operand:SI 6 "const1248_operand" "n")]
+ UNSPEC_VSIBADDR)])
(mem:BLK (scratch))
- (match_operand:V4DI 4 "register_operand" "x")
- (match_operand:VI4F_128 5 "register_operand" "1")
- (match_operand:SI 6 "const1248_operand" "n")]
+ (match_operand:VI4F_128 5 "register_operand" "1")]
UNSPEC_GATHER))
(clobber (match_scratch:VI4F_128 1 "=&x"))]
"TARGET_AVX2"
- "v<sseintprefix>gatherq<ssemodesuffix>\t{%1, (%3, %4, %p6), %0|%0, (%3, %4, %p6), %1}"
+ "v<sseintprefix>gatherq<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])