summaryrefslogtreecommitdiff
path: root/gcc/config/sparc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-03 06:17:33 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-03 06:17:33 +0000
commit5c9447f2404b5360adfe707fe0589fef24099834 (patch)
treef12f99097c64e655b05b6ea40051798edb1a610e /gcc/config/sparc
parente1a03d245eace16ae09fbcda2f7480a99845ccf1 (diff)
downloadgcc-5c9447f2404b5360adfe707fe0589fef24099834.tar.gz
2011-10-03 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 179444 using svnmerge. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@179445 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r--gcc/config/sparc/niagara.md2
-rw-r--r--gcc/config/sparc/niagara2.md4
-rw-r--r--gcc/config/sparc/predicates.md5
-rw-r--r--gcc/config/sparc/sparc-c.c12
-rw-r--r--gcc/config/sparc/sparc-modes.def1
-rw-r--r--gcc/config/sparc/sparc.c205
-rw-r--r--gcc/config/sparc/sparc.h2
-rw-r--r--gcc/config/sparc/sparc.md237
-rw-r--r--gcc/config/sparc/sparc.opt10
-rw-r--r--gcc/config/sparc/ultra1_2.md2
-rw-r--r--gcc/config/sparc/ultra3.md2
-rw-r--r--gcc/config/sparc/visintrin.h273
12 files changed, 719 insertions, 36 deletions
diff --git a/gcc/config/sparc/niagara.md b/gcc/config/sparc/niagara.md
index a75088b9c9b..c7a2245ecfa 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 f261ac1ec5a..fa07becd822 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/predicates.md b/gcc/config/sparc/predicates.md
index 21399b5902a..f0be14997af 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -24,11 +24,6 @@
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
-;; Return true if OP is the one constant for MODE.
-(define_predicate "const_one_operand"
- (and (match_code "const_int,const_double,const_vector")
- (match_test "op == CONST1_RTX (mode)")))
-
;; Return true if the integer representation of OP is
;; all-ones.
(define_predicate "const_all_ones_operand"
diff --git a/gcc/config/sparc/sparc-c.c b/gcc/config/sparc/sparc-c.c
index 6e30950df0f..c18797045ae 100644
--- a/gcc/config/sparc/sparc-c.c
+++ b/gcc/config/sparc/sparc-c.c
@@ -45,7 +45,17 @@ sparc_target_macros (void)
cpp_assert (parse_in, "machine=sparc");
}
- if (TARGET_VIS)
+ if (TARGET_VIS3)
+ {
+ cpp_define (parse_in, "__VIS__=0x300");
+ cpp_define (parse_in, "__VIS=0x300");
+ }
+ else 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-modes.def b/gcc/config/sparc/sparc-modes.def
index 6284700867d..ed135ccc1b7 100644
--- a/gcc/config/sparc/sparc-modes.def
+++ b/gcc/config/sparc/sparc-modes.def
@@ -43,5 +43,6 @@ CC_MODE (CCFP);
CC_MODE (CCFPE);
/* Vector modes. */
+VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index c8c0677b4b8..4df9f6a8088 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_VIS3|MASK_FMAF},
/* UltraSPARC T4 */
- { MASK_ISA, MASK_V9 | MASK_FMAF},
+ { MASK_ISA, MASK_V9|MASK_VIS2|MASK_VIS3|MASK_FMAF},
};
const struct cpu_table *cpu;
unsigned int i;
@@ -857,9 +857,17 @@ 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;
+
+ /* -mvis3 implies -mvis2 and -mvis */
+ if (TARGET_VIS3)
+ target_flags |= MASK_VIS2 | MASK_VIS;
+
+ /* Don't allow -mvis, -mvis2, -mvis3, or -mfmaf if FPU is disabled. */
if (! TARGET_FPU)
- target_flags &= ~(MASK_VIS | MASK_FMAF);
+ target_flags &= ~(MASK_VIS | MASK_VIS2 | MASK_VIS3 | MASK_FMAF);
/* -mvis assumes UltraSPARC+, so we are sure v9 instructions
are available.
@@ -9192,6 +9200,10 @@ sparc_vis_init_builtins (void)
tree di_ftype_v8qi_v8qi_di = build_function_type_list (intDI_type_node,
v8qi, v8qi,
intDI_type_node, 0);
+ tree di_ftype_v8qi_v8qi = build_function_type_list (intDI_type_node,
+ v8qi, v8qi, 0);
+ tree si_ftype_v8qi_v8qi = build_function_type_list (intSI_type_node,
+ v8qi, v8qi, 0);
tree di_ftype_di_di = build_function_type_list (intDI_type_node,
intDI_type_node,
intDI_type_node, 0);
@@ -9222,6 +9234,8 @@ sparc_vis_init_builtins (void)
intDI_type_node, 0);
tree di_ftype_void = build_function_type_list (intDI_type_node,
void_type_node, 0);
+ tree void_ftype_si = build_function_type_list (void_type_node,
+ intSI_type_node, 0);
/* Packing and expanding vectors. */
def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis,
@@ -9300,6 +9314,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 +9344,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 +9438,121 @@ 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);
+ }
+
+ if (TARGET_VIS3)
+ {
+ if (TARGET_ARCH64)
+ {
+ def_builtin ("__builtin_vis_cmask8", CODE_FOR_cmask8di_vis,
+ void_ftype_di);
+ def_builtin ("__builtin_vis_cmask16", CODE_FOR_cmask16di_vis,
+ void_ftype_di);
+ def_builtin ("__builtin_vis_cmask32", CODE_FOR_cmask32di_vis,
+ void_ftype_di);
+ }
+ else
+ {
+ def_builtin ("__builtin_vis_cmask8", CODE_FOR_cmask8si_vis,
+ void_ftype_si);
+ def_builtin ("__builtin_vis_cmask16", CODE_FOR_cmask16si_vis,
+ void_ftype_si);
+ def_builtin ("__builtin_vis_cmask32", CODE_FOR_cmask32si_vis,
+ void_ftype_si);
+ }
+
+ def_builtin_const ("__builtin_vis_fchksm16", CODE_FOR_fchksm16_vis,
+ v4hi_ftype_v4hi_v4hi);
+
+ def_builtin_const ("__builtin_vis_fsll16", CODE_FOR_fsll16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fslas16", CODE_FOR_fslas16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fsrl16", CODE_FOR_fsrl16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fsra16", CODE_FOR_fsra16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fsll32", CODE_FOR_fsll32_vis,
+ v2si_ftype_v2si_v2si);
+ def_builtin_const ("__builtin_vis_fslas32", CODE_FOR_fslas32_vis,
+ v2si_ftype_v2si_v2si);
+ def_builtin_const ("__builtin_vis_fsrl32", CODE_FOR_fsrl32_vis,
+ v2si_ftype_v2si_v2si);
+ def_builtin_const ("__builtin_vis_fsra32", CODE_FOR_fsra32_vis,
+ v2si_ftype_v2si_v2si);
+
+ if (TARGET_ARCH64)
+ def_builtin_const ("__builtin_vis_pdistn", CODE_FOR_pdistndi_vis,
+ di_ftype_v8qi_v8qi);
+ else
+ def_builtin_const ("__builtin_vis_pdistn", CODE_FOR_pdistnsi_vis,
+ si_ftype_v8qi_v8qi);
+
+ def_builtin_const ("__builtin_vis_fmean16", CODE_FOR_fmean16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fpadd64", CODE_FOR_fpadd64_vis,
+ di_ftype_di_di);
+ def_builtin_const ("__builtin_vis_fpsub64", CODE_FOR_fpsub64_vis,
+ di_ftype_di_di);
+
+ def_builtin_const ("__builtin_vis_fpadds16", CODE_FOR_fpadds16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fpadds16s", CODE_FOR_fpadds16s_vis,
+ v2hi_ftype_v2hi_v2hi);
+ def_builtin_const ("__builtin_vis_fpsubs16", CODE_FOR_fpsubs16_vis,
+ v4hi_ftype_v4hi_v4hi);
+ def_builtin_const ("__builtin_vis_fpsubs16s", CODE_FOR_fpsubs16s_vis,
+ v2hi_ftype_v2hi_v2hi);
+ def_builtin_const ("__builtin_vis_fpadds32", CODE_FOR_fpadds32_vis,
+ v2si_ftype_v2si_v2si);
+ def_builtin_const ("__builtin_vis_fpadds32s", CODE_FOR_fpadds32s_vis,
+ v1si_ftype_v1si_v1si);
+ def_builtin_const ("__builtin_vis_fpsubs32", CODE_FOR_fpsubs32_vis,
+ v2si_ftype_v2si_v2si);
+ def_builtin_const ("__builtin_vis_fpsubs32s", CODE_FOR_fpsubs32s_vis,
+ v1si_ftype_v1si_v1si);
+
+ if (TARGET_ARCH64)
+ {
+ def_builtin_const ("__builtin_vis_fucmple8", CODE_FOR_fucmple8di_vis,
+ di_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpne8", CODE_FOR_fucmpne8di_vis,
+ di_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpgt8", CODE_FOR_fucmpgt8di_vis,
+ di_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8di_vis,
+ di_ftype_v8qi_v8qi);
+ }
+ else
+ {
+ def_builtin_const ("__builtin_vis_fucmple8", CODE_FOR_fucmple8si_vis,
+ si_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpne8", CODE_FOR_fucmpne8si_vis,
+ si_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpgt8", CODE_FOR_fucmpgt8si_vis,
+ si_ftype_v8qi_v8qi);
+ def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8si_vis,
+ si_ftype_v8qi_v8qi);
+ }
+ }
}
/* Handle TARGET_EXPAND_BUILTIN target hook.
@@ -9428,16 +9587,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]);
}
@@ -9553,11 +9714,27 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
tree rtype = TREE_TYPE (TREE_TYPE (fndecl));
enum insn_code icode = (enum insn_code) DECL_FUNCTION_CODE (fndecl);
- if (ignore
- && icode != CODE_FOR_alignaddrsi_vis
- && icode != CODE_FOR_alignaddrdi_vis
- && icode != CODE_FOR_wrgsr_vis)
- return build_zero_cst (rtype);
+ if (ignore)
+ {
+ switch (icode)
+ {
+ case CODE_FOR_alignaddrsi_vis:
+ case CODE_FOR_alignaddrdi_vis:
+ case CODE_FOR_wrgsr_vis:
+ case CODE_FOR_bmasksi_vis:
+ case CODE_FOR_bmaskdi_vis:
+ case CODE_FOR_cmask8si_vis:
+ case CODE_FOR_cmask8di_vis:
+ case CODE_FOR_cmask16si_vis:
+ case CODE_FOR_cmask16di_vis:
+ case CODE_FOR_cmask32si_vis:
+ case CODE_FOR_cmask32di_vis:
+ break;
+
+ default:
+ return build_zero_cst (rtype);
+ }
+ }
switch (icode)
{
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index cccd4446c91..fa943877550 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1868,6 +1868,8 @@ extern int sparc_indent_opcode;
#define AS_NIAGARA3_FLAG "b"
#undef TARGET_FMAF
#define TARGET_FMAF 0
+#undef TARGET_VIS3
+#define TARGET_VIS3 0
#else
#define AS_NIAGARA3_FLAG "d"
#endif
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index d9bcd310770..699074682f6 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -72,6 +72,20 @@
(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)
+ (UNSPEC_CMASK8 77)
+ (UNSPEC_CMASK16 78)
+ (UNSPEC_CMASK32 79)
+ (UNSPEC_FCHKSM16 80)
+ (UNSPEC_PDISTN 81)
+ (UNSPEC_FUCMP 82)
])
(define_constants
@@ -187,12 +201,16 @@
(define_mode_iterator V64 [DF V2SI V4HI V8QI])
(define_mode_iterator V64I [DI V2SI V4HI V8QI])
+(define_mode_iterator V64N8 [V2SI V4HI])
+
;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
;; 'f' for all DF/TFmode values, including those that are specific to the v8.
+(define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
+(define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
;; Attribute for cpu type.
;; These must match the values for enum processor_type in sparc.h.
@@ -240,7 +258,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"
@@ -5796,9 +5814,20 @@
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
return "sll\t%1, %2, %0";
}
- [(set (attr "type")
- (if_then_else (match_operand 2 "const_one_operand" "")
- (const_string "ialu") (const_string "shift")))])
+ [(set_attr "type" "shift")])
+
+(define_insn "*ashlsi3_extend"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "arith_operand" "rI"))))]
+ "TARGET_ARCH64"
+{
+ if (GET_CODE (operands[2]) == CONST_INT)
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
+ return "sll\t%1, %2, %0";
+}
+ [(set_attr "type" "shift")])
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -5825,9 +5854,7 @@
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
return "sllx\t%1, %2, %0";
}
- [(set (attr "type")
- (if_then_else (match_operand 2 "const_one_operand" "")
- (const_string "ialu") (const_string "shift")))])
+ [(set_attr "type" "shift")])
;; XXX UGH!
(define_insn "ashldi3_v8plus"
@@ -5962,10 +5989,23 @@
}
[(set_attr "type" "shift")])
+(define_insn "*lshrsi3_extend0"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "arith_operand" "rI"))))]
+ "TARGET_ARCH64"
+ {
+ if (GET_CODE (operands[2]) == CONST_INT)
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
+ return "srl\t%1, %2, %0";
+ }
+ [(set_attr "type" "shift")])
+
;; This handles the case where
;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
;; but combiner "simplifies" it for us.
-(define_insn "*lshrsi3_extend"
+(define_insn "*lshrsi3_extend1"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "arith_operand" "r")) 0)
@@ -8151,13 +8191,13 @@
(define_mode_iterator GCM [V4HI V2SI])
(define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
-(define_insn "fcmp<gcond:code><gcm_name><P:mode>_vis"
+(define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
(match_operand:GCM 2 "register_operand" "e"))]
UNSPEC_FCMP))]
"TARGET_VIS"
- "fcmp<gcond:code><gcm_name>\t%1, %2, %0"
+ "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
[(set_attr "type" "fpmul")
(set_attr "fptype" "double")])
@@ -8188,4 +8228,181 @@
"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")])
+
+;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
+(define_insn "cmask8<P:mode>_vis"
+ [(set (reg:DI GSR_REG)
+ (unspec:DI [(match_operand:P 0 "register_operand" "r")
+ (reg:DI GSR_REG)]
+ UNSPEC_CMASK8))]
+ "TARGET_VIS3"
+ "cmask8\t%r0")
+
+(define_insn "cmask16<P:mode>_vis"
+ [(set (reg:DI GSR_REG)
+ (unspec:DI [(match_operand:P 0 "register_operand" "r")
+ (reg:DI GSR_REG)]
+ UNSPEC_CMASK16))]
+ "TARGET_VIS3"
+ "cmask16\t%r0")
+
+(define_insn "cmask32<P:mode>_vis"
+ [(set (reg:DI GSR_REG)
+ (unspec:DI [(match_operand:P 0 "register_operand" "r")
+ (reg:DI GSR_REG)]
+ UNSPEC_CMASK32))]
+ "TARGET_VIS3"
+ "cmask32\t%r0")
+
+(define_insn "fchksm16_vis"
+ [(set (match_operand:V4HI 0 "register_operand" "=e")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
+ (match_operand:V4HI 2 "register_operand" "e")]
+ UNSPEC_FCHKSM16))]
+ "TARGET_VIS3"
+ "fchksm16\t%1, %2, %0")
+
+(define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
+(define_code_attr vis3_shift_insn
+ [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
+
+(define_insn "<vis3_shift_insn><vbits>_vis"
+ [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
+ (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
+ (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
+ "TARGET_VIS3"
+ "<vis3_shift_insn><vbits>\t%1, %2, %0")
+
+(define_insn "pdistn<mode>_vis"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
+ (match_operand:V8QI 2 "register_operand" "e")]
+ UNSPEC_PDISTN))]
+ "TARGET_VIS3"
+ "pdistn\t%1, %2, %0")
+
+(define_insn "fmean16_vis"
+ [(set (match_operand:V4HI 0 "register_operand" "=e")
+ (truncate:V4HI
+ (lshiftrt:V4SI
+ (plus:V4SI
+ (plus:V4SI
+ (zero_extend:V4SI
+ (match_operand:V4HI 1 "register_operand" "e"))
+ (zero_extend:V4SI
+ (match_operand:V4HI 2 "register_operand" "e")))
+ (const_vector:V4SI [(const_int 1) (const_int 1)
+ (const_int 1) (const_int 1)]))
+ (const_int 1))))]
+ "TARGET_VIS3"
+ "fmean16\t%1, %2, %0")
+
+(define_insn "fpadd64_vis"
+ [(set (match_operand:DI 0 "register_operand" "=e")
+ (plus:DI (match_operand:DI 1 "register_operand" "e")
+ (match_operand:DI 2 "register_operand" "e")))]
+ "TARGET_VIS3"
+ "fpadd64\t%1, %2, %0")
+
+(define_insn "fpsub64_vis"
+ [(set (match_operand:DI 0 "register_operand" "=e")
+ (minus:DI (match_operand:DI 1 "register_operand" "e")
+ (match_operand:DI 2 "register_operand" "e")))]
+ "TARGET_VIS3"
+ "fpsub64\t%1, %2, %0")
+
+(define_mode_iterator VASS [V4HI V2SI V2HI SI])
+(define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
+(define_code_attr vis3_addsub_ss_insn
+ [(ss_plus "fpadds") (ss_minus "fpsubs")])
+
+(define_insn "<vis3_addsub_ss_insn><vbits>_vis"
+ [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
+ (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
+ (match_operand:VASS 2 "register_operand" "<vconstr>")))]
+ "TARGET_VIS3"
+ "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
+
+(define_insn "fucmp<code>8<P:mode>_vis"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
+ (match_operand:V8QI 2 "register_operand" "e"))]
+ UNSPEC_FUCMP))]
+ "TARGET_VIS3"
+ "fucmp<code>8\t%1, %2, %0")
+
(include "sync.md")
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 6be6a7590d0..613ae731c8e 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -59,7 +59,15 @@ 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
+
+mvis3
+Target Report Mask(VIS3)
+Use UltraSPARC Visual Instruction Set version 3.0 extensions
mfmaf
Target Report Mask(FMAF)
diff --git a/gcc/config/sparc/ultra1_2.md b/gcc/config/sparc/ultra1_2.md
index 46002055716..9cdebab620b 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 c6a9f89ea1a..c891e356205 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 3bef099c7e6..32e44e55810 100644
--- a/gcc/config/sparc/visintrin.h
+++ b/gcc/config/sparc/visintrin.h
@@ -354,4 +354,277 @@ __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);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_cmask8 (long __A)
+{
+ return __builtin_vis_cmask8 (__A);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_cmask16 (long __A)
+{
+ return __builtin_vis_cmask16 (__A);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_cmask32 (long __A)
+{
+ return __builtin_vis_cmask32 (__A);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fchksm16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fchksm16 (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsll16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fsll16 (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fslas16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fslas16 (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsrl16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fsrl16 (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsra16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fsra16 (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsll32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fsll32 (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fslas32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fslas32 (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsrl32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fsrl32 (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fsra32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fsra32 (__A, __B);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_pdistn (__v8qi __A, __v8qi __B)
+{
+ return __builtin_vis_pdistn (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fmean16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fmean16 (__A, __B);
+}
+
+extern __inline __i64
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpadd64 (__i64 __A, __i64 __B)
+{
+ return __builtin_vis_fpadd64 (__A, __B);
+}
+
+extern __inline __i64
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpsub64 (__i64 __A, __i64 __B)
+{
+ return __builtin_vis_fpsub64 (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpadds16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fpadds16 (__A, __B);
+}
+
+extern __inline __v2hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpadds16s (__v2hi __A, __v2hi __B)
+{
+ return __builtin_vis_fpadds16s (__A, __B);
+}
+
+extern __inline __v4hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpsubs16 (__v4hi __A, __v4hi __B)
+{
+ return __builtin_vis_fpsubs16 (__A, __B);
+}
+
+extern __inline __v2hi
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpsubs16s (__v2hi __A, __v2hi __B)
+{
+ return __builtin_vis_fpsubs16s (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpadds32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fpadds32 (__A, __B);
+}
+
+extern __inline __v1si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpadds32s (__v1si __A, __v1si __B)
+{
+ return __builtin_vis_fpadds32s (__A, __B);
+}
+
+extern __inline __v2si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpsubs32 (__v2si __A, __v2si __B)
+{
+ return __builtin_vis_fpsubs32 (__A, __B);
+}
+
+extern __inline __v1si
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fpsubs32s (__v1si __A, __v1si __B)
+{
+ return __builtin_vis_fpsubs32s (__A, __B);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fucmple8 (__v8qi __A, __v8qi __B)
+{
+ return __builtin_vis_fucmple8 (__A, __B);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fucmpne8 (__v8qi __A, __v8qi __B)
+{
+ return __builtin_vis_fucmpne8 (__A, __B);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fucmpgt8 (__v8qi __A, __v8qi __B)
+{
+ return __builtin_vis_fucmpgt8 (__A, __B);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__vis_fucmpeq8 (__v8qi __A, __v8qi __B)
+{
+ return __builtin_vis_fucmpeq8 (__A, __B);
+}
+
#endif /* _VISINTRIN_H_INCLUDED */