+(define_mode_iterator VM32 [V1SI V2HI V4QI])
+(define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
+(define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
+
+(define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
+(define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
+ (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
+(define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
+ (V1DI "double") (V2SI "double") (V4HI "double")
+ (V8QI "double")])
+
+(define_expand "mov<VMALL:mode>"
+ [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
+ (match_operand:VMALL 1 "general_operand" ""))]
+ "TARGET_VIS"
+{
+ if (sparc_expand_move (<VMALL:MODE>mode, operands))
+ DONE;
+})
+
+(define_insn "*mov<VM32:mode>_insn"
+ [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
+ (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
+ "TARGET_VIS
+ && (register_operand (operands[0], <VM32:MODE>mode)
+ || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
+ "@
+ fzeros\t%0
+ fones\t%0
+ fsrc1s\t%1, %0
+ ld\t%1, %0
+ st\t%1, %0
+ st\t%r1, %0
+ ld\t%1, %0
+ st\t%1, %0
+ mov\t%1, %0
+ movstouw\t%1, %0
+ movwtos\t%1, %0"
+ [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
+ (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
+
+(define_insn "*mov<VM64:mode>_insn_sp64"
+ [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
+ (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
+ "TARGET_VIS
+ && TARGET_ARCH64
+ && (register_operand (operands[0], <VM64:MODE>mode)
+ || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
+ "@
+ fzero\t%0
+ fone\t%0
+ fsrc1\t%1, %0
+ ldd\t%1, %0
+ std\t%1, %0
+ stx\t%r1, %0
+ ldx\t%1, %0
+ stx\t%1, %0
+ movdtox\t%1, %0
+ movxtod\t%1, %0
+ mov\t%1, %0"
+ [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*")
+ (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
+
+(define_insn "*mov<VM64:mode>_insn_sp32"
+ [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
+ (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
+ "TARGET_VIS
+ && ! TARGET_ARCH64
+ && (register_operand (operands[0], <VM64:MODE>mode)
+ || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
+ "@
+ fzero\t%0
+ fone\t%0
+ fsrc1\t%1, %0
+ #
+ #
+ ldd\t%1, %0
+ std\t%1, %0
+ stx\t%r1, %0
+ ldd\t%1, %0
+ std\t%1, %0
+ #
+ #"
+ [(set_attr "type" "fga,fga,fga,*,*,fpload,fpstore,store,load,store,*,*")
+ (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
+ (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
+
+(define_split
+ [(set (match_operand:VM64 0 "memory_operand" "")
+ (match_operand:VM64 1 "register_operand" ""))]
+ "reload_completed
+ && TARGET_VIS
+ && ! TARGET_ARCH64
+ && (((REGNO (operands[1]) % 2) != 0)
+ || ! mem_min_alignment (operands[0], 8))
+ && offsettable_memref_p (operands[0])"
+ [(clobber (const_int 0))]
+{
+ rtx word0, word1;
+
+ word0 = adjust_address (operands[0], SImode, 0);
+ word1 = adjust_address (operands[0], SImode, 4);
+
+ emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
+ emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
+ DONE;
+})
+
+(define_split
+ [(set (match_operand:VM64 0 "register_operand" "")
+ (match_operand:VM64 1 "register_operand" ""))]
+ "reload_completed
+ && TARGET_VIS
+ && ! TARGET_ARCH64
+ && sparc_split_regreg_legitimate (operands[0], operands[1])"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_highpart (SImode, set_dest);
+ dest2 = gen_lowpart (SImode, set_dest);
+ src1 = gen_highpart (SImode, set_src);
+ src2 = gen_lowpart (SImode, set_src);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movsi (dest2, src2));
+ emit_insn (gen_movsi (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_movsi (dest1, src1));
+ emit_insn (gen_movsi (dest2, src2));
+ }
+ DONE;
+})
+
+(define_expand "vec_init<mode>"
+ [(match_operand:VMALL 0 "register_operand" "")
+ (match_operand:VMALL 1 "" "")]
+ "TARGET_VIS"
+{
+ sparc_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+