diff options
author | David S. Miller <davem@davemloft.net> | 2011-09-30 07:54:07 +0000 |
---|---|---|
committer | David S. Miller <davem@gcc.gnu.org> | 2011-09-30 00:54:07 -0700 |
commit | c4728c6b20436826e469927a76fa12b89f7cf11e (patch) | |
tree | ef2752591fdb528a5b9df11ad312ebf11a2712dd /gcc/config/sparc | |
parent | 3aaedee02143cb24a313a147f787d4211844a042 (diff) | |
download | gcc-c4728c6b20436826e469927a76fa12b89f7cf11e.zip gcc-c4728c6b20436826e469927a76fa12b89f7cf11e.tar.gz gcc-c4728c6b20436826e469927a76fa12b89f7cf11e.tar.bz2 |
Add sparc VIS 2.0 builtins, intrinsics, and option to control them.
gcc/
* config/sparc/sparc.opt (VIS2): New option.
* doc/invoke.texi: Document it.
* config/sparc/sparc.md (UNSPEC_EDGE8N, UNSPEC_EDGE8LN,
UNSPEC_EDGE16N, UNSPEC_EDGE16LN, UNSPEC_EDGE32N,
UNSPEC_EDGE32LN, UNSPEC_BSHUFFLE): New unspecs.
(define_attr type): New insn type 'edgen'.
(bmask<P:mode>_vis, bshuffle<V64I:mode>_vis, edge8n<P:mode>_vis,
edge8ln<P:mode>_vis, edge16n<P:mode>_vis, edge16ln<P:mode>_vis,
edge32n<P:mode>_vis, edge32ln<P:mode>_vis): New insn VIS 2.0
patterns.
* niagara.md: Handle edgen.
* niagara2.md: Likewise.
* ultra1_2.md: Likewise.
* ultra3.md: Likewise.
* config/sparc/sparc-c.c (sparc_target_macros): Define __VIS__
to 0x200 when TARGET_VIS2.
* config/sparc/sparc.c (sparc_option_override): Set MASK_VIS2 by
default when targetting capable cpus. TARGET_VIS2 implies
TARGET_VIS, clear and it when TARGET_FPU is disabled.
(sparc_vis_init_builtins): Emit new VIS 2.0 builtins.
(sparc_expand_builtin): Fix predicate indexing when builtin returns
void.
(sparc_fold_builtin): Do not eliminate bmask when result is ignored.
* config/sparc/visintrin.h (__vis_bmask, __vis_bshuffledi,
__vis_bshufflev2si, __vis_bshufflev4hi, __vis_bshufflev8qi,
__vis_edge8n, __vis_edge8ln, __vis_edge16n, __vis_edge16ln,
__vis_edge32n, __vis_edge32ln): New VIS 2.0 interfaces.
* doc/extend.texi: Document new VIS 2.0 builtins.
gcc/testsuite/
* gcc.target/sparc/bmaskbshuf.c: New test.
* gcc.target/sparc/edgen.c: New test.
From-SVN: r179376
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r-- | gcc/config/sparc/niagara.md | 2 | ||||
-rw-r--r-- | gcc/config/sparc/niagara2.md | 4 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-c.c | 7 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 77 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 85 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.opt | 6 | ||||
-rw-r--r-- | gcc/config/sparc/ultra1_2.md | 2 | ||||
-rw-r--r-- | gcc/config/sparc/ultra3.md | 2 | ||||
-rw-r--r-- | gcc/config/sparc/visintrin.h | 77 |
9 files changed, 244 insertions, 18 deletions
diff --git a/gcc/config/sparc/niagara.md b/gcc/config/sparc/niagara.md index a75088b..c7a2245 100644 --- a/gcc/config/sparc/niagara.md +++ b/gcc/config/sparc/niagara.md @@ -114,5 +114,5 @@ */ (define_insn_reservation "niag_vis" 8 (and (eq_attr "cpu" "niagara") - (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,gsr,array")) + (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,edgen,gsr,array")) "niag_pipe*8") diff --git a/gcc/config/sparc/niagara2.md b/gcc/config/sparc/niagara2.md index f261ac1..fa07bec 100644 --- a/gcc/config/sparc/niagara2.md +++ b/gcc/config/sparc/niagara2.md @@ -111,10 +111,10 @@ (define_insn_reservation "niag2_vis" 6 (and (eq_attr "cpu" "niagara2") - (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,array,gsr")) + (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,edgen,array,gsr")) "niag2_pipe*6") (define_insn_reservation "niag3_vis" 9 (and (eq_attr "cpu" "niagara3") - (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,array,gsr")) + (eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,edgen,array,gsr")) "niag2_pipe*9") diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c index 6e30950..0f2bee1 100644 --- a/gcc/config/sparc/sparc-c.c +++ b/gcc/config/sparc/sparc-c.c @@ -45,7 +45,12 @@ sparc_target_macros (void) cpp_assert (parse_in, "machine=sparc"); } - if (TARGET_VIS) + if (TARGET_VIS2) + { + cpp_define (parse_in, "__VIS__=0x200"); + cpp_define (parse_in, "__VIS=0x200"); + } + else if (TARGET_VIS) { cpp_define (parse_in, "__VIS__=0x100"); cpp_define (parse_in, "__VIS=0x100"); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index c8c0677..9863174 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -769,16 +769,16 @@ sparc_option_override (void) /* UltraSPARC III */ /* ??? Check if %y issue still holds true. */ { MASK_ISA, - MASK_V9|MASK_DEPRECATED_V8_INSNS}, + MASK_V9|MASK_DEPRECATED_V8_INSNS|MASK_VIS2}, /* UltraSPARC T1 */ { MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS}, /* UltraSPARC T2 */ - { MASK_ISA, MASK_V9}, + { MASK_ISA, MASK_V9|MASK_VIS2}, /* UltraSPARC T3 */ - { MASK_ISA, MASK_V9 | MASK_FMAF}, + { MASK_ISA, MASK_V9|MASK_VIS2|MASK_FMAF}, /* UltraSPARC T4 */ - { MASK_ISA, MASK_V9 | MASK_FMAF}, + { MASK_ISA, MASK_V9|MASK_VIS2|MASK_FMAF}, }; const struct cpu_table *cpu; unsigned int i; @@ -857,9 +857,13 @@ sparc_option_override (void) if (target_flags_explicit & MASK_FPU) target_flags = (target_flags & ~MASK_FPU) | fpu; - /* Don't allow -mvis or -mfmaf if FPU is disabled. */ + /* -mvis2 implies -mvis */ + if (TARGET_VIS2) + target_flags |= MASK_VIS; + + /* Don't allow -mvis, -mvis2, or -mfmaf if FPU is disabled. */ if (! TARGET_FPU) - target_flags &= ~(MASK_VIS | MASK_FMAF); + target_flags &= ~(MASK_VIS | MASK_VIS2 | MASK_FMAF); /* -mvis assumes UltraSPARC+, so we are sure v9 instructions are available. @@ -9300,6 +9304,21 @@ sparc_vis_init_builtins (void) di_ftype_ptr_ptr); def_builtin_const ("__builtin_vis_edge32l", CODE_FOR_edge32ldi_vis, di_ftype_ptr_ptr); + if (TARGET_VIS2) + { + def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8ndi_vis, + di_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lndi_vis, + di_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16ndi_vis, + di_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lndi_vis, + di_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32ndi_vis, + di_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lndi_vis, + di_ftype_ptr_ptr); + } } else { @@ -9315,6 +9334,21 @@ sparc_vis_init_builtins (void) si_ftype_ptr_ptr); def_builtin_const ("__builtin_vis_edge32l", CODE_FOR_edge32lsi_vis, si_ftype_ptr_ptr); + if (TARGET_VIS2) + { + def_builtin_const ("__builtin_vis_edge8n", CODE_FOR_edge8nsi_vis, + si_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge8ln", CODE_FOR_edge8lnsi_vis, + si_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge16n", CODE_FOR_edge16nsi_vis, + si_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge16ln", CODE_FOR_edge16lnsi_vis, + si_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge32n", CODE_FOR_edge32nsi_vis, + si_ftype_ptr_ptr); + def_builtin_const ("__builtin_vis_edge32ln", CODE_FOR_edge32lnsi_vis, + si_ftype_ptr_ptr); + } } /* Pixel compare. */ @@ -9394,6 +9428,25 @@ sparc_vis_init_builtins (void) def_builtin_const ("__builtin_vis_array32", CODE_FOR_array32si_vis, si_ftype_si_si); } + + if (TARGET_VIS2) + { + /* Byte mask and shuffle */ + if (TARGET_ARCH64) + def_builtin ("__builtin_vis_bmask", CODE_FOR_bmaskdi_vis, + di_ftype_di_di); + else + def_builtin ("__builtin_vis_bmask", CODE_FOR_bmasksi_vis, + si_ftype_si_si); + def_builtin ("__builtin_vis_bshufflev4hi", CODE_FOR_bshufflev4hi_vis, + v4hi_ftype_v4hi_v4hi); + def_builtin ("__builtin_vis_bshufflev8qi", CODE_FOR_bshufflev8qi_vis, + v8qi_ftype_v8qi_v8qi); + def_builtin ("__builtin_vis_bshufflev2si", CODE_FOR_bshufflev2si_vis, + v2si_ftype_v2si_v2si); + def_builtin ("__builtin_vis_bshuffledi", CODE_FOR_bshuffledi_vis, + di_ftype_di_di); + } } /* Handle TARGET_EXPAND_BUILTIN target hook. @@ -9428,16 +9481,18 @@ sparc_expand_builtin (tree exp, rtx target, FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) { const struct insn_operand_data *insn_op; + int idx; if (arg == error_mark_node) return NULL_RTX; arg_count++; - insn_op = &insn_data[icode].operand[arg_count - !nonvoid]; + idx = arg_count - !nonvoid; + insn_op = &insn_data[icode].operand[idx]; op[arg_count] = expand_normal (arg); - if (! (*insn_data[icode].operand[arg_count].predicate) (op[arg_count], - insn_op->mode)) + if (! (*insn_data[icode].operand[idx].predicate) (op[arg_count], + insn_op->mode)) op[arg_count] = copy_to_mode_reg (insn_op->mode, op[arg_count]); } @@ -9556,7 +9611,9 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, if (ignore && icode != CODE_FOR_alignaddrsi_vis && icode != CODE_FOR_alignaddrdi_vis - && icode != CODE_FOR_wrgsr_vis) + && icode != CODE_FOR_wrgsr_vis + && icode != CODE_FOR_bmasksi_vis + && icode != CODE_FOR_bmaskdi_vis) return build_zero_cst (rtype); switch (icode) diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 2def8d1..0446955 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -72,6 +72,14 @@ (UNSPEC_SP_SET 60) (UNSPEC_SP_TEST 61) + + (UNSPEC_EDGE8N 70) + (UNSPEC_EDGE8LN 71) + (UNSPEC_EDGE16N 72) + (UNSPEC_EDGE16LN 73) + (UNSPEC_EDGE32N 74) + (UNSPEC_EDGE32LN 75) + (UNSPEC_BSHUFFLE 76) ]) (define_constants @@ -240,7 +248,7 @@ fpcmp, fpmul,fpdivs,fpdivd, fpsqrts,fpsqrtd, - fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,array, + fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array, cmove, ialuX, multi,savew,flushw,iflush,trap" @@ -8188,4 +8196,79 @@ "array32\t%r1, %r2, %0" [(set_attr "type" "array")]) +(define_insn "bmask<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (plus:P (match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ"))) + (clobber (reg:SI GSR_REG))] + "TARGET_VIS2" + "bmask\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "bshuffle<V64I:mode>_vis" + [(set (match_operand:V64I 0 "register_operand" "=e") + (unspec:V64I [(match_operand:V64I 1 "register_operand" "e") + (match_operand:V64I 2 "register_operand" "e")] + UNSPEC_BSHUFFLE)) + (use (reg:SI GSR_REG))] + "TARGET_VIS2" + "bshuffle\t%1, %2, %0" + [(set_attr "type" "fga") + (set_attr "fptype" "double")]) + +;; VIS 2.0 adds edge variants which do not set the condition codes +(define_insn "edge8n<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE8N))] + "TARGET_VIS2" + "edge8n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge8ln<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE8LN))] + "TARGET_VIS2" + "edge8ln\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge16n<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE16N))] + "TARGET_VIS2" + "edge16n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge16ln<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE16LN))] + "TARGET_VIS2" + "edge16ln\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge32n<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE32N))] + "TARGET_VIS2" + "edge32n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge32ln<P:mode>_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "rJ") + (match_operand:P 2 "register_operand" "rJ")] + UNSPEC_EDGE32LN))] + "TARGET_VIS2" + "edge32ln\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + (include "sync.md") diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt index 6be6a75..a7b60c8 100644 --- a/gcc/config/sparc/sparc.opt +++ b/gcc/config/sparc/sparc.opt @@ -59,7 +59,11 @@ Compile for V8+ ABI mvis Target Report Mask(VIS) -Use UltraSPARC Visual Instruction Set extensions +Use UltraSPARC Visual Instruction Set version 1.0 extensions + +mvis2 +Target Report Mask(VIS2) +Use UltraSPARC Visual Instruction Set version 2.0 extensions mfmaf Target Report Mask(FMAF) diff --git a/gcc/config/sparc/ultra1_2.md b/gcc/config/sparc/ultra1_2.md index 4600205..9cdebab 100644 --- a/gcc/config/sparc/ultra1_2.md +++ b/gcc/config/sparc/ultra1_2.md @@ -94,7 +94,7 @@ (define_insn_reservation "us1_simple_ieu1" 1 (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "compare,edge,array")) + (eq_attr "type" "compare,edge,edgen,array")) "us1_ieu1 + us1_slot012") (define_insn_reservation "us1_ialuX" 1 diff --git a/gcc/config/sparc/ultra3.md b/gcc/config/sparc/ultra3.md index c6a9f89..c891e35 100644 --- a/gcc/config/sparc/ultra3.md +++ b/gcc/config/sparc/ultra3.md @@ -56,7 +56,7 @@ (define_insn_reservation "us3_array" 2 (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "array")) + (eq_attr "type" "array,edgen")) "us3_ms + us3_slotany, nothing") ;; ??? Not entirely accurate. diff --git a/gcc/config/sparc/visintrin.h b/gcc/config/sparc/visintrin.h index 3bef099..1688301 100644 --- a/gcc/config/sparc/visintrin.h +++ b/gcc/config/sparc/visintrin.h @@ -354,4 +354,81 @@ __vis_array32 (long __A, long __B) return __builtin_vis_array32 (__A, __B); } +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_bmask (long __A, long __B) +{ + return __builtin_vis_bmask (__A, __B); +} + +extern __inline __i64 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_bshuffledi (__i64 __A, __i64 __B) +{ + return __builtin_vis_bshuffledi (__A, __B); +} + +extern __inline __v2si +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_bshufflev2si (__v2si __A, __v2si __B) +{ + return __builtin_vis_bshufflev2si (__A, __B); +} + +extern __inline __v4hi +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_bshufflev4hi (__v4hi __A, __v4hi __B) +{ + return __builtin_vis_bshufflev4hi (__A, __B); +} + +extern __inline __v8qi +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_bshufflev8qi (__v8qi __A, __v8qi __B) +{ + return __builtin_vis_bshufflev8qi (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge8n (void *__A, void *__B) +{ + return __builtin_vis_edge8n (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge8ln (void *__A, void *__B) +{ + return __builtin_vis_edge8ln (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge16n (void *__A, void *__B) +{ + return __builtin_vis_edge16n (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge16ln (void *__A, void *__B) +{ + return __builtin_vis_edge16ln (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge32n (void *__A, void *__B) +{ + return __builtin_vis_edge32n (__A, __B); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_edge32ln (void *__A, void *__B) +{ + return __builtin_vis_edge32ln (__A, __B); +} + #endif /* _VISINTRIN_H_INCLUDED */ |