Commit 6cf538da by Robert Suchanek Committed by Robert Suchanek

Add support for MIPS SIMD Architecture (MSA).

gcc/
	* config.gcc: Add MSA header file for mips*-*-* target.
	* config/mips/constraints.md (YI, YC, YZ, Unv5, Uuv5, Usv5, Uuv6)
	(Ubv8i, Urv8):	New constraints.
	* config/mips/mips-ftypes.def: Add function types for MSA
	builtins.
	* config/mips/mips-modes.def (V16QI, V8HI, V4SI, V2DI, V4SF)
	(V2DF, V32QI, V16HI, V8SI, V4DI, V8SF, V4DF): New modes.
	* config/mips/mips-msa.md: New file.
	* config/mips/mips-protos.h
	(mips_split_128bit_const_insns): New prototype.
	(mips_msa_idiv_insns): Likewise.
	(mips_split_128bit_move): Likewise.
	(mips_split_128bit_move_p): Likewise.
	(mips_split_msa_copy_d): Likewise.
	(mips_split_msa_insert_d): Likewise.
	(mips_split_msa_fill_d): Likewise.
	(mips_expand_msa_branch): Likewise.
	(mips_const_vector_same_val_p): Likewise.
	(mips_const_vector_same_bytes_p): Likewise.
	(mips_const_vector_same_int_p): Likewise.
	(mips_const_vector_shuffle_set_p): Likewise.
	(mips_const_vector_bitimm_set_p): Likewise.
	(mips_const_vector_bitimm_clr_p): Likewise.
	(mips_msa_vec_parallel_const_half): Likewise.
	(mips_msa_output_division): Likewise.
	(mips_ldst_scaled_shift): Likewise.
	(mips_expand_vec_cond_expr): Likewise.
	* config/mips/mips.c (enum mips_builtin_type): Add
	MIPS_BUILTIN_MSA_TEST_BRANCH.
	(mips_gen_const_int_vector_shuffle): New prototype.
	(mips_const_vector_bitimm_set_p): New function.
	(mips_const_vector_bitimm_clr_p): Likewise.
	(mips_const_vector_same_val_p): Likewise.
	(mips_const_vector_same_bytes_p): Likewise.
	(mips_const_vector_same_int_p): Likewise.
	(mips_const_vector_shuffle_set_p): Likewise.
	(mips_symbol_insns): Forbid loading symbols via immediate for
	MSA.
	(mips_valid_offset_p): Limit offset to 10-bit for MSA loads and
	stores.
	(mips_valid_lo_sum_p): Forbid loadings symbols via %lo(base) for
	MSA.
	(mips_lx_address_p): Add support load indexed address for MSA.
	(mips_address_insns): Add calculation of instructions needed for
	stores and loads for MSA.
	(mips_const_insns): Move CONST_DOUBLE below CONST_VECTOR.  Handle
	CONST_VECTOR for MSA and let it fall through.
	(mips_ldst_scaled_shift): New function.
	(mips_subword_at_byte): Likewise.
	(mips_msa_idiv_insns): Likewise.
	(mips_legitimize_move): Validate MSA moves.
	(mips_rtx_costs): Add UNGE, UNGT, UNLE, UNLT cases.  Add
	calculation of costs for MSA division.
	(mips_split_move_p): Check if MSA moves need splitting.
	(mips_split_move): Split MSA moves if necessary.
	(mips_split_128bit_move_p): New function.
	(mips_split_128bit_move): Likewise.
	(mips_split_msa_copy_d): Likewise.
	(mips_split_msa_insert_d): Likewise.
	(mips_split_msa_fill_d): Likewise.
	(mips_output_move): Handle MSA moves.
	(mips_expand_msa_branch): New function.
	(mips_print_operand): Add 'E', 'B', 'w', 'v' and 'V' modifiers.
	Reinstate 'y' modifier.
	(mips_file_start): Add MSA .gnu_attribute.
	(mips_hard_regno_mode_ok_p): Allow TImode and 128-bit vectors in
	FPRs.
	(mips_hard_regno_nregs): Always return 1 for MSA supported mode.
	(mips_class_max_nregs): Add register size for MSA supported mode.
	(mips_cannot_change_mode_class): Allow conversion between MSA
	vector modes and TImode.
	(mips_mode_ok_for_mov_fmt_p): Allow MSA to use move.v
	instruction.
	(mips_secondary_reload_class): Force MSA loads/stores via memory.
	(mips_preferred_simd_mode): Add preffered modes for MSA.
	(mips_vector_mode_supported_p): Add MSA supported modes.
	(mips_autovectorize_vector_sizes): New function.
	(mips_msa_output_division): Likewise.
	(MSA_BUILTIN, MIPS_BUILTIN_DIRECT_NO_TARGET)
	(MSA_NO_TARGET_BUILTIN, MSA_BUILTIN_TEST_BRANCH): New macros.
	(CODE_FOR_msa_adds_s_b, CODE_FOR_msa_adds_s_h)
	(CODE_FOR_msa_adds_s_w, CODE_FOR_msa_adds_s_d)
	(CODE_FOR_msa_adds_u_b, CODE_FOR_msa_adds_u_h)
	(CODE_FOR_msa_adds_u_w, CODE_FOR_msa_adds_u_du
	(CODE_FOR_msa_addv_b, CODE_FOR_msa_addv_h, CODE_FOR_msa_addv_w)
	(CODE_FOR_msa_addv_d, CODE_FOR_msa_and_v, CODE_FOR_msa_bmnz_v)
	(CODE_FOR_msa_bmnzi_b, CODE_FOR_msa_bmz_v, CODE_FOR_msa_bmzi_b)
	(CODE_FOR_msa_bnz_v, CODE_FOR_msa_bz_v, CODE_FOR_msa_bsel_v)
	(CODE_FOR_msa_bseli_b, CODE_FOR_msa_ceqi_h, CODE_FOR_msa_ceqi_w)
	(CODE_FOR_msa_ceqi_d, CODE_FOR_msa_clti_s_b)
	(CODE_FOR_msa_clti_s_h, CODE_FOR_msa_clti_s_w)
	(CODE_FOR_msa_clti_s_d, CODE_FOR_msa_clti_u_b)
	(CODE_FOR_msa_clti_u_h, CODE_FOR_msa_clti_u_w)
	(CODE_FOR_msa_clti_u_d, CODE_FOR_msa_clei_s_b)
	(CODE_FOR_msa_clei_s_h, CODE_FOR_msa_clei_s_w)
	(CODE_FOR_msa_clei_s_d, CODE_FOR_msa_clei_u_b)
	(CODE_FOR_msa_clei_u_h, CODE_FOR_msa_clei_u_w)
	(CODE_FOR_msa_clei_u_d, CODE_FOR_msa_div_s_b)
	(CODE_FOR_msa_div_s_h, CODE_FOR_msa_div_s_w)
	(CODE_FOR_msa_div_s_d, CODE_FOR_msa_div_u_b)
	(CODE_FOR_msa_div_u_h, CODE_FOR_msa_div_u_w)
	(CODE_FOR_msa_div_u_d, CODE_FOR_msa_fadd_w, CODE_FOR_msa_fadd_d)
	(CODE_FOR_msa_fexdo_w, CODE_FOR_msa_ftrunc_s_w)
	(CODE_FOR_msa_ftrunc_s_d, CODE_FOR_msa_ftrunc_u_w)
	(CODE_FOR_msa_ftrunc_u_d, CODE_FOR_msa_ffint_s_w)
	(CODE_FOR_msa_ffint_s_d, CODE_FOR_msa_ffint_u_w)
	(CODE_FOR_msa_ffint_u_d, CODE_FOR_msa_fsub_w)
	(CODE_FOR_msa_fsub_d, CODE_FOR_msa_fmsub_d, CODE_FOR_msa_fmadd_w)
	(CODE_FOR_msa_fmadd_d, CODE_FOR_msa_fmsub_w, CODE_FOR_msa_fmul_w)
	(CODE_FOR_msa_fmul_d, CODE_FOR_msa_fdiv_w, CODE_FOR_msa_fdiv_d)
	(CODE_FOR_msa_fmax_w, CODE_FOR_msa_fmax_d, CODE_FOR_msa_fmax_a_w)
	(CODE_FOR_msa_fmax_a_d, CODE_FOR_msa_fmin_w, CODE_FOR_msa_fmin_d)
	(CODE_FOR_msa_fmin_a_w, CODE_FOR_msa_fmin_a_d)
	(CODE_FOR_msa_fsqrt_w, CODE_FOR_msa_fsqrt_d)
	(CODE_FOR_msa_max_s_b, CODE_FOR_msa_max_s_h)
	(CODE_FOR_msa_max_s_w, CODE_FOR_msa_max_s_d)
	(CODE_FOR_msa_max_u_b, CODE_FOR_msa_max_u_h)
	(CODE_FOR_msa_max_u_w, CODE_FOR_msa_max_u_d)
	(CODE_FOR_msa_min_s_b, CODE_FOR_msa_min_s_h)
	(CODE_FOR_msa_min_s_w, CODE_FOR_msa_min_s_d)
	(CODE_FOR_msa_min_u_b, CODE_FOR_msa_min_u_h)
	(CODE_FOR_msa_min_u_w, CODE_FOR_msa_min_u_d)
	(CODE_FOR_msa_mod_s_b, CODE_FOR_msa_mod_s_h)
	(CODE_FOR_msa_mod_s_w, CODE_FOR_msa_mod_s_d)
	(CODE_FOR_msa_mod_u_b, CODE_FOR_msa_mod_u_h)
	(CODE_FOR_msa_mod_u_w, CODE_FOR_msa_mod_u_d)
	(CODE_FOR_msa_mod_s_b, CODE_FOR_msa_mod_s_h)
	(CODE_FOR_msa_mod_s_w, CODE_FOR_msa_mod_s_d)
	(CODE_FOR_msa_mod_u_b, CODE_FOR_msa_mod_u_h)
	(CODE_FOR_msa_mod_u_w, CODE_FOR_msa_mod_u_d)
	(CODE_FOR_msa_mulv_b, CODE_FOR_msa_mulv_h, CODE_FOR_msa_mulv_w)
	(CODE_FOR_msa_mulv_d, CODE_FOR_msa_nlzc_b, CODE_FOR_msa_nlzc_h)
	(CODE_FOR_msa_nlzc_w, CODE_FOR_msa_nlzc_d, CODE_FOR_msa_nor_v)
	(CODE_FOR_msa_or_v, CODE_FOR_msa_ori_b, CODE_FOR_msa_nori_b)
	(CODE_FOR_msa_pcnt_b, CODE_FOR_msa_pcnt_h, CODE_FOR_msa_pcnt_w)
	(CODE_FOR_msa_pcnt_d, CODE_FOR_msa_xor_v, CODE_FOR_msa_xori_b)
	(CODE_FOR_msa_sll_b, CODE_FOR_msa_sll_h, CODE_FOR_msa_sll_w)
	(CODE_FOR_msa_sll_d, CODE_FOR_msa_slli_b, CODE_FOR_msa_slli_h)
	(CODE_FOR_msa_slli_w, CODE_FOR_msa_slli_d, CODE_FOR_msa_sra_b)
	(CODE_FOR_msa_sra_h, CODE_FOR_msa_sra_w, CODE_FOR_msa_sra_d)
	(CODE_FOR_msa_srai_b, CODE_FOR_msa_srai_h, CODE_FOR_msa_srai_w)
	(CODE_FOR_msa_srai_d, CODE_FOR_msa_srl_b, CODE_FOR_msa_srl_h)
	(CODE_FOR_msa_srl_w, CODE_FOR_msa_srl_d, CODE_FOR_msa_srli_b)
	(CODE_FOR_msa_srli_h, CODE_FOR_msa_srli_w, CODE_FOR_msa_srli_d)
	(CODE_FOR_msa_subv_b, CODE_FOR_msa_subv_h, CODE_FOR_msa_subv_w)
	(CODE_FOR_msa_subv_d, CODE_FOR_msa_subvi_b, CODE_FOR_msa_subvi_h)
	(CODE_FOR_msa_subvi_w, CODE_FOR_msa_subvi_d, CODE_FOR_msa_move_v)
	(CODE_FOR_msa_vshf_b, CODE_FOR_msa_vshf_h, CODE_FOR_msa_vshf_w)
	(CODE_FOR_msa_vshf_d, CODE_FOR_msa_ilvod_d, CODE_FOR_msa_ilvev_d)
	(CODE_FOR_msa_pckod_d, CODE_FOR_msa_pckdev_d, CODE_FOR_msa_ldi_b)
	(CODE_FOR_msa_ldi_hi, CODE_FOR_msa_ldi_w)
	(CODE_FOR_msa_ldi_d): New code_aliasing macros.
	(mips_builtins): Add MSA sll_b, sll_h, sll_w, sll_d, slli_b,
	slli_h,	slli_w, slli_d, sra_b, sra_h, sra_w, sra_d, srai_b,
	srai_h, srai_w,	srai_d, srar_b, srar_h, srar_w, srar_d, srari_b,
	srari_h, srari_w, srari_d, srl_b, srl_h, srl_w, srl_d, srli_b,
	srli_h, srli_w, srli_d, srlr_b, srlr_h, srlr_w, srlr_d, srlri_b,
	srlri_h, srlri_w, srlri_d, bclr_b, bclr_h, bclr_w, bclr_d,
	bclri_b, bclri_h, bclri_w, bclri_d, bset_b, bset_h, bset_w,
	bset_d, bseti_b, bseti_h, bseti_w, bseti_d, bneg_b, bneg_h,
	bneg_w, bneg_d, bnegi_b, bnegi_h, bnegi_w, bnegi_d, binsl_b,
	binsl_h, binsl_w, binsl_d, binsli_b, binsli_h, binsli_w,
	binsli_d, binsr_b, binsr_h, binsr_w, binsr_d, binsri_b, binsri_h,
	binsri_w, binsri_d, addv_b, addv_h, addv_w, addv_d, addvi_b,
	addvi_h, addvi_w, addvi_d, subv_b, subv_h, subv_w, subv_d,
	subvi_b, subvi_h, subvi_w, subvi_d, max_s_b, max_s_h, max_s_w,
	max_s_d, maxi_s_b, maxi_s_h, maxi_s_w, maxi_s_d, max_u_b,
	max_u_h, max_u_w, max_u_d, maxi_u_b, maxi_u_h, maxi_u_w,
	maxi_u_d, min_s_b, min_s_h, min_s_w, min_s_d, mini_s_b, mini_s_h,
	mini_s_w, mini_s_d, min_u_b, min_u_h, min_u_w, min_u_d, mini_u_b,
	mini_u_h, mini_u_w, mini_u_d, max_a_b, max_a_h, max_a_w, max_a_d,
	min_a_b, min_a_h, min_a_w, min_a_d, ceq_b, ceq_h, ceq_w, ceq_d,
	ceqi_b, ceqi_h, ceqi_w, ceqi_d, clt_s_b, clt_s_h, clt_s_w,
	clt_s_d, clti_s_b, clti_s_h, clti_s_w, clti_s_d, clt_u_b,
	clt_u_h, clt_u_w, clt_u_d, clti_u_b, clti_u_h, clti_u_w,
	clti_u_d, cle_s_b, cle_s_h, cle_s_w, cle_s_d, clei_s_b, clei_s_h,
	clei_s_w, clei_s_d, cle_u_b, cle_u_h, cle_u_w, cle_u_d, clei_u_b,
	clei_u_h, clei_u_w, clei_u_d, ld_b, ld_h, ld_w, ld_d, st_b, st_h,
	st_w, st_d, sat_s_b, sat_s_h, sat_s_w, sat_s_d, sat_u_b, sat_u_h,
	sat_u_w, sat_u_d, add_a_b, add_a_h, add_a_w, add_a_d, adds_a_b,
	adds_a_h, adds_a_w, adds_a_d, adds_s_b, adds_s_h, adds_s_w,
	adds_s_d, adds_u_b, adds_u_h, adds_u_w, adds_u_d, ave_s_b,
	ave_s_h, ave_s_w, ave_s_d, ave_u_b, ave_u_h, ave_u_w, ave_u_d,
	aver_s_b, aver_s_h, aver_s_w, aver_s_d, aver_u_b, aver_u_h,
	aver_u_w, aver_u_d, subs_s_b, subs_s_h, subs_s_w, subs_s_d,
	subs_u_b, subs_u_h, subs_u_w, subs_u_d, subsuu_s_b, subsuu_s_h,
	subsuu_s_w, subsuu_s_d, subsus_u_b, subsus_u_h, subsus_u_w,
	subsus_u_d, asub_s_b, asub_s_h, asub_s_w, asub_s_d, asub_u_b,
	asub_u_h, asub_u_w, asub_u_d, mulv_b, mulv_h, mulv_w, mulv_d,
	maddv_b, maddv_h, maddv_w, maddv_d, msubv_b, msubv_h, msubv_w,
	msubv_d, div_s_b, div_s_h, div_s_w, div_s_d, div_u_b, div_u_h,
	div_u_w, div_u_d, hadd_s_h, hadd_s_w, hadd_s_d, hadd_u_h,
	hadd_u_w, hadd_u_d, hsub_s_h, hsub_s_w, hsub_s_d, hsub_u_h,
	hsub_u_w, hsub_u_d, mod_s_b, mod_s_h, mod_s_w, mod_s_d, mod_u_b,
	mod_u_h, mod_u_w, mod_u_d, dotp_s_h, dotp_s_w, dotp_s_d,
	dotp_u_h, dotp_u_w, dotp_u_d, dpadd_s_h, dpadd_s_w, dpadd_s_d,
	dpadd_u_h, dpadd_u_w, dpadd_u_d, dpsub_s_h, dpsub_s_w, dpsub_s_d,
	dpsub_u_h, dpsub_u_w, dpsub_u_d, sld_b, sld_h, sld_w, sld_d,
	sldi_b, sldi_h, sldi_w, sldi_d, splat_b, splat_h, splat_w,
	splat_d, splati_b, splati_h, splati_w, splati_d, pckev_b,
	pckev_h, pckev_w, pckev_d, pckod_b, pckod_h, pckod_w, pckod_d,
	ilvl_b, ilvl_h, ilvl_w, ilvl_d, ilvr_b, ilvr_h, ilvr_w, ilvr_d,
	ilvev_b, ilvev_h, ilvev_w, ilvev_d, ilvod_b, ilvod_h, ilvod_w,
	ilvod_d, vshf_b, vshf_h, vshf_w, vshf_d, and_v, andi_b, or_v,
	ori_b, nor_v, nori_b, xor_v, xori_b, bmnz_v, bmnzi_b, bmz_v,
	bmzi_b, bsel_v, bseli_b, shf_b, shf_h, shf_w, bnz_v, bz_v,
	fill_b, fill_h, fill_w, fill_d, pcnt_b, pcnt_h, pcnt_w,
	pcnt_d, nloc_b, nloc_h, nloc_w, nloc_d, nlzc_b, nlzc_h, nlzc_w,
	nlzc_d, copy_s_b, copy_s_h, copy_s_w, copy_s_d, copy_u_b,
	copy_u_h, copy_u_w, copy_u_d, insert_b, insert_h, insert_w,
	insert_d, insve_b, insve_h, insve_w, insve_d, bnz_b, bnz_h,
	bnz_w, bnz_d, bz_b, bz_h, bz_w, bz_d, ldi_b, ldi_h, ldi_w, ldi_d,
	fcaf_w, fcaf_d, fcor_w, fcor_d, fcun_w, fcun_d, fcune_w, fcune_d,
	fcueq_w, fcueq_d, fceq_w, fceq_d, fcne_w, fcne_d, fclt_w, fclt_d,
	fcult_w, fcult_d, fcle_w, fcle_d, fcule_w, fcule_d, fsaf_w,
	fsaf_d, fsor_w, fsor_d, fsun_w, fsun_d, fsune_w, fsune_d,
	fsueq_w, fsueq_d, fseq_w, fseq_d, fsne_w, fsne_d, fslt_w,
	fslt_d, fsult_w, fsult_d, fsle_w, fsle_d, fsule_w, fsule_d,
	fadd_w,	fadd_d, fsub_w, fsub_d, fmul_w, fmul_d, fdiv_w, fdiv_d,
	fmadd_w, fmadd_d, fmsub_w, fmsub_d, fexp2_w, fexp2_d, fexdo_h,
	fexdo_w, ftq_h, ftq_w, fmin_w, fmin_d, fmin_a_w, fmin_a_d,
	fmax_w, fmax_d, fmax_a_w, fmax_a_d, mul_q_h, mul_q_w, mulr_q_h,
	mulr_q_w, madd_q_h, madd_q_w, maddr_q_h, maddr_q_w, msub_q_h,
	msub_q_w, msubr_q_h, msubr_q_w, fclass_w, fclass_d, fsqrt_w,
	fsqrt_d, frcp_w, frcp_d, frint_w, frint_d, frsqrt_w, frsqrt_d,
	flog2_w, flog2_d, fexupl_w, fexupl_d, fexupr_w, fexupr_d, ffql_w,
	ffql_d, ffqr_w, ffqr_d, ftint_s_w, ftint_s_d, ftint_u_w,
	ftint_u_d, ftrunc_s_w, ftrunc_s_d, ftrunc_u_w, ftrunc_u_d,
	ffint_s_w, ffint_s_d, ffint_u_w, ffint_u_d, ctcmsa, cfcmsa,
	move_v builtins.
	(mips_get_builtin_decl_index): New array.
	(MIPS_ATYPE_QI, MIPS_ATYPE_HI, MIPS_ATYPE_V2DI, MIPS_ATYPE_V4SI)
	(MIPS_ATYPE_V8HI, MIPS_ATYPE_V16QI, MIPS_ATYPE_V2DF)
	(MIPS_ATYPE_V4SF, MIPS_ATYPE_UV2DI, MIPS_ATYPE_UV4SI)
	(MIPS_ATYPE_UV8HI, MIPS_ATYPE_UV16QI): New.
	(mips_init_builtins): Initialize mips_get_builtin_decl_index
	array.
	(TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Define target
	hook.
	(mips_expand_builtin_insn): Prepare operands for
	CODE_FOR_msa_addvi_b, CODE_FOR_msa_addvi_h, CODE_FOR_msa_addvi_w,
	CODE_FOR_msa_addvi_d, CODE_FOR_msa_clti_u_b,
	CODE_FOR_msa_clti_u_h, CODE_FOR_msa_clti_u_w,
	CODE_FOR_msa_clti_u_d, CODE_FOR_msa_clei_u_b,
	CODE_FOR_msa_clei_u_h, CODE_FOR_msa_clei_u_w,
	CODE_FOR_msa_clei_u_d, CODE_FOR_msa_maxi_u_b,
	CODE_FOR_msa_maxi_u_h, CODE_FOR_msa_maxi_u_w,
	CODE_FOR_msa_maxi_u_d, CODE_FOR_msa_mini_u_b,
	CODE_FOR_msa_mini_u_h, CODE_FOR_msa_mini_u_w,
	CODE_FOR_msa_mini_u_d, CODE_FOR_msa_subvi_b,
	CODE_FOR_msa_subvi_h, CODE_FOR_msa_subvi_w, CODE_FOR_msa_subvi_d,
	CODE_FOR_msa_ceqi_b, CODE_FOR_msa_ceqi_h, CODE_FOR_msa_ceqi_w,
	CODE_FOR_msa_ceqi_d, CODE_FOR_msa_clti_s_b,
	CODE_FOR_msa_clti_s_h, CODE_FOR_msa_clti_s_w,
	CODE_FOR_msa_clti_s_d, CODE_FOR_msa_clei_s_b,
	CODE_FOR_msa_clei_s_h, CODE_FOR_msa_clei_s_w,
	CODE_FOR_msa_clei_s_d, CODE_FOR_msa_maxi_s_b,
	CODE_FOR_msa_maxi_s_h, CODE_FOR_msa_maxi_s_w,
	CODE_FOR_msa_maxi_s_d, CODE_FOR_msa_mini_s_b,
	CODE_FOR_msa_mini_s_h, CODE_FOR_msa_mini_s_w,
	CODE_FOR_msa_mini_s_d, CODE_FOR_msa_andi_b, CODE_FOR_msa_ori_b,
	CODE_FOR_msa_nori_b, CODE_FOR_msa_xori_b, CODE_FOR_msa_bmzi_b,
	CODE_FOR_msa_bmnzi_b, CODE_FOR_msa_bseli_b, CODE_FOR_msa_fill_b,
	CODE_FOR_msa_fill_h, CODE_FOR_msa_fill_w, CODE_FOR_msa_fill_d,
	CODE_FOR_msa_ilvl_b, CODE_FOR_msa_ilvl_h, CODE_FOR_msa_ilvl_w,
	CODE_FOR_msa_ilvl_d, CODE_FOR_msa_ilvr_b, CODE_FOR_msa_ilvr_h,
	CODE_FOR_msa_ilvr_w, CODE_FOR_msa_ilvr_d, CODE_FOR_msa_ilvev_b,
	CODE_FOR_msa_ilvev_h, CODE_FOR_msa_ilvev_w, CODE_FOR_msa_ilvod_b,
	CODE_FOR_msa_ilvod_h, CODE_FOR_msa_ilvod_w, CODE_FOR_msa_pckev_b,
	CODE_FOR_msa_pckev_h, CODE_FOR_msa_pckev_w, CODE_FOR_msa_pckod_b,
	CODE_FOR_msa_pckod_h, CODE_FOR_msa_pckod_w, CODE_FOR_msa_slli_b,
	CODE_FOR_msa_slli_h, CODE_FOR_msa_slli_w, CODE_FOR_msa_slli_d,
	CODE_FOR_msa_srai_b, CODE_FOR_msa_srai_h, CODE_FOR_msa_srai_w,
	CODE_FOR_msa_srai_d, CODE_FOR_msa_srli_b, CODE_FOR_msa_srli_h,
	CODE_FOR_msa_srli_w, CODE_FOR_msa_srli_d, CODE_FOR_msa_insert_b,
	CODE_FOR_msa_insert_h, CODE_FOR_msa_insert_w,
	CODE_FOR_msa_insert_d, CODE_FOR_msa_insve_b,
	CODE_FOR_msa_insve_h, CODE_FOR_msa_insve_w, CODE_FOR_msa_insve_d,
	CODE_FOR_msa_shf_b, CODE_FOR_msa_shf_h, CODE_FOR_msa_shf_w,
	CODE_FOR_msa_shf_w_f, CODE_FOR_msa_vshf_b, CODE_FOR_msa_vshf_h,
	CODE_FOR_msa_vshf_w, CODE_FOR_msa_vshf_d.
	(mips_expand_builtin): Add case for MIPS_BULTIN_MSA_TEST_BRANCH.
	(mips_set_compression_mode): Disallow MSA with MIPS16 code.
	(mips_option_override): -mmsa requires -mfp64 and -mhard-float.
	These are set implicitly and an error is reported if overridden.
	(mips_expand_builtin_msa_test_branch): New function.
	(mips_expand_msa_shuffle): Likewise.
	(MAX_VECT_LEN): Increase maximum length of a vector to 16 bytes.
	(TARGET_SCHED_REASSOCIATION_WIDTH): Define target hook.
	(TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Likewise.
	(mips_expand_vec_unpack): Add support for MSA.
	(mips_expand_vector_init): Likewise.
	(mips_expand_vi_constant): Use CONST0_RTX (element_mode)
	instead of const0_rtx.
	(mips_msa_vec_parallel_const_half): New function.
	(mips_gen_const_int_vector): Likewise.
	(mips_gen_const_int_vector_shuffle): Likewise.
	(mips_expand_msa_cmp): Likewise.
	(mips_expand_vec_cond_expr): Likewise.
	* config/mips/mips.h
	(TARGET_CPU_CPP_BUILTINS): Add __mips_msa and __mips_msa_width.
	(OPTION_DEFAULT_SPECS): Ignore --with-fp-32 if -mmsa is
	specified.
	(ASM_SPEC): Pass mmsa and mno-msa to the assembler.
	(ISA_HAS_MSA): New macro.
	(UNITS_PER_MSA_REG): Likewise.
	(BITS_PER_MSA_REG): Likewise.
	(BIGGEST_ALIGNMENT): Redefine using ISA_HAS_MSA.
	(MSA_REG_FIRST): New macro.
	(MSA_REG_LAST): Likewise.
	(MSA_REG_NUM): Likewise.
	(MSA_REG_P): Likewise.
	(MSA_REG_RTX_P): Likewise.
	(MSA_SUPPORTED_MODE_P): Likewise.
	(HARD_REGNO_CALL_PART_CLOBBERED): Redefine using TARGET_MSA.
	(ADDITIONAL_REGISTER_NAMES): Add named registers $w0-$w31.
	* config/mips/mips.md: Include mips-msa.md.
	(alu_type): Add simd_add.
	(mode): Add V2DI, V4SI, V8HI, V16QI, V2DF, V4SF.
	(type): Add simd_div, simd_fclass, simd_flog2, simd_fadd,
	simd_fcvt, simd_fmul, simd_fmadd, simd_fdiv, simd_bitins,
	simd_bitmov, simd_insert, simd_sld, simd_mul, simd_fcmp,
	simd_fexp2, simd_int_arith, simd_bit, simd_shift, simd_splat,
	simd_fill, simd_permute, simd_shf, simd_sat, simd_pcnt,
	simd_copy, simd_branch, simd_cmsa, simd_fminmax, simd_logic,
	simd_move, simd_load, simd_store.  Choose "multi" for moves
	for "qword_mode".
	(qword_mode): New attribute.
	(insn_count): Add instruction count for quad moves.
	Increase the count for MIPS SIMD division.
	(UNITMODE): Add UNITMODEs for vector types.
	(addsub): New code iterator.
	* config/mips/mips.opt (mmsa): New option.
	* config/mips/msa.h: New file.
	* config/mips/mti-elf.h: Don't infer -mfpxx if -mmsa is
	specified.
	* config/mips/mti-linux.h: Likewise.
	* config/mips/predicates.md
	(const_msa_branch_operand): New constraint.
	(const_uimm3_operand): Likewise.
	(const_uimm4_operand): Likewise.
	(const_uimm5_operand): Likewise.
	(const_uimm8_operand): Likewise.
	(const_imm5_operand): Likewise.
	(aq10b_operand): Likewise.
	(aq10h_operand): Likewise.
	(aq10w_operand): Likewise.
	(aq10d_operand): Likewise.
	(const_m1_operand): Likewise.
	(reg_or_m1_operand): Likewise.
	(const_exp_2_operand): Likewise.
	(const_exp_4_operand): Likewise.
	(const_exp_8_operand): Likewise.
	(const_exp_16_operand): Likewise.
	(const_vector_same_val_operand): Likewise.
	(const_vector_same_simm5_operand): Likewise.
	(const_vector_same_uimm5_operand): Likewise.
	(const_vector_same_uimm6_operand): Likewise.
	(const_vector_same_uimm8_operand): Likewise.
	(par_const_vector_shf_set_operand): Likewise.
	(reg_or_vector_same_val_operand): Likewise.
	(reg_or_vector_same_simm5_operand): Likewise.
	(reg_or_vector_same_uimm6_operand): Likewise.
	* doc/extend.texi (MIPS SIMD Architecture Functions): New
	section.
	* doc/invoke.texi (-mmsa): Document new option.

Co-Authored-By: Chao-ying Fu <chao-ying.fu@imgtec.com>
Co-Authored-By: Graham Stott <graham.stott@imgtec.com>
Co-Authored-By: Matthew Fortune <matthew.fortune@imgtec.com>
Co-Authored-By: Sameera Deshpande <sameera.deshpande@imgtec.com>

From-SVN: r236030
parent ad103b01
...@@ -427,7 +427,7 @@ microblaze*-*-*) ...@@ -427,7 +427,7 @@ microblaze*-*-*)
;; ;;
mips*-*-*) mips*-*-*)
cpu_type=mips cpu_type=mips
extra_headers="loongson.h" extra_headers="loongson.h msa.h"
extra_objs="frame-header-opt.o" extra_objs="frame-header-opt.o"
extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt" extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt"
;; ;;
......
...@@ -308,6 +308,61 @@ ...@@ -308,6 +308,61 @@
"@internal" "@internal"
(match_operand 0 "low_bitmask_operand")) (match_operand 0 "low_bitmask_operand"))
(define_constraint "YI"
"@internal
A replicated vector const in which the replicated value is in the range
[-512,511]."
(and (match_code "const_vector")
(match_test "mips_const_vector_same_int_p (op, mode, -512, 511)")))
(define_constraint "YC"
"@internal
A replicated vector const in which the replicated value has a single
bit set."
(and (match_code "const_vector")
(match_test "mips_const_vector_bitimm_set_p (op, mode)")))
(define_constraint "YZ"
"@internal
A replicated vector const in which the replicated value has a single
bit clear."
(and (match_code "const_vector")
(match_test "mips_const_vector_bitimm_clr_p (op, mode)")))
(define_constraint "Unv5"
"@internal
A replicated vector const in which the replicated value is in the range
[-31,0]."
(and (match_code "const_vector")
(match_test "mips_const_vector_same_int_p (op, mode, -31, 0)")))
(define_constraint "Uuv5"
"@internal
A replicated vector const in which the replicated value is in the range
[0,31]."
(and (match_code "const_vector")
(match_test "mips_const_vector_same_int_p (op, mode, 0, 31)")))
(define_constraint "Usv5"
"@internal
A replicated vector const in which the replicated value is in the range
[-16,15]."
(and (match_code "const_vector")
(match_test "mips_const_vector_same_int_p (op, mode, -16, 15)")))
(define_constraint "Uuv6"
"@internal
A replicated vector const in which the replicated value is in the range
[0,63]."
(and (match_code "const_vector")
(match_test "mips_const_vector_same_int_p (op, mode, 0, 63)")))
(define_constraint "Urv8"
"@internal
A replicated vector const with replicated byte values as well as elements"
(and (match_code "const_vector")
(match_test "mips_const_vector_same_bytes_p (op, mode)")))
(define_memory_constraint "ZC" (define_memory_constraint "ZC"
"A memory operand whose address is formed by a base register and offset "A memory operand whose address is formed by a base register and offset
that is suitable for use in instructions with the same addressing mode that is suitable for use in instructions with the same addressing mode
......
...@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
Please keep this list lexicographically sorted by the LIST argument. */ Please keep this list lexicographically sorted by the LIST argument. */
DEF_MIPS_FTYPE (1, (DF, DF)) DEF_MIPS_FTYPE (1, (DF, DF))
DEF_MIPS_FTYPE (2, (DF, DF, DF)) DEF_MIPS_FTYPE (2, (DF, DF, DF))
DEF_MIPS_FTYPE (1, (DF, V2DF))
DEF_MIPS_FTYPE (2, (DI, DI, DI)) DEF_MIPS_FTYPE (2, (DI, DI, DI))
DEF_MIPS_FTYPE (2, (DI, DI, SI)) DEF_MIPS_FTYPE (2, (DI, DI, SI))
...@@ -45,6 +46,7 @@ DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI)) ...@@ -45,6 +46,7 @@ DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI))
DEF_MIPS_FTYPE (2, (DI, POINTER, SI)) DEF_MIPS_FTYPE (2, (DI, POINTER, SI))
DEF_MIPS_FTYPE (2, (DI, SI, SI)) DEF_MIPS_FTYPE (2, (DI, SI, SI))
DEF_MIPS_FTYPE (2, (DI, USI, USI)) DEF_MIPS_FTYPE (2, (DI, USI, USI))
DEF_MIPS_FTYPE (2, (DI, V2DI, UQI))
DEF_MIPS_FTYPE (2, (INT, DF, DF)) DEF_MIPS_FTYPE (2, (INT, DF, DF))
DEF_MIPS_FTYPE (2, (INT, SF, SF)) DEF_MIPS_FTYPE (2, (INT, SF, SF))
...@@ -54,23 +56,51 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2SF, V2SF)) ...@@ -54,23 +56,51 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2SF, V2SF))
DEF_MIPS_FTYPE (1, (SF, SF)) DEF_MIPS_FTYPE (1, (SF, SF))
DEF_MIPS_FTYPE (2, (SF, SF, SF)) DEF_MIPS_FTYPE (2, (SF, SF, SF))
DEF_MIPS_FTYPE (1, (SF, V2SF)) DEF_MIPS_FTYPE (1, (SF, V2SF))
DEF_MIPS_FTYPE (1, (SF, V4SF))
DEF_MIPS_FTYPE (2, (SI, DI, SI)) DEF_MIPS_FTYPE (2, (SI, DI, SI))
DEF_MIPS_FTYPE (2, (SI, POINTER, SI)) DEF_MIPS_FTYPE (2, (SI, POINTER, SI))
DEF_MIPS_FTYPE (1, (SI, SI)) DEF_MIPS_FTYPE (1, (SI, SI))
DEF_MIPS_FTYPE (2, (SI, SI, SI)) DEF_MIPS_FTYPE (2, (SI, SI, SI))
DEF_MIPS_FTYPE (3, (SI, SI, SI, SI)) DEF_MIPS_FTYPE (3, (SI, SI, SI, SI))
DEF_MIPS_FTYPE (1, (SI, UQI))
DEF_MIPS_FTYPE (1, (SI, UV16QI))
DEF_MIPS_FTYPE (1, (SI, UV2DI))
DEF_MIPS_FTYPE (1, (SI, UV4SI))
DEF_MIPS_FTYPE (1, (SI, UV8HI))
DEF_MIPS_FTYPE (2, (SI, V16QI, UQI))
DEF_MIPS_FTYPE (1, (SI, V2HI)) DEF_MIPS_FTYPE (1, (SI, V2HI))
DEF_MIPS_FTYPE (2, (SI, V2HI, V2HI)) DEF_MIPS_FTYPE (2, (SI, V2HI, V2HI))
DEF_MIPS_FTYPE (1, (SI, V4QI)) DEF_MIPS_FTYPE (1, (SI, V4QI))
DEF_MIPS_FTYPE (2, (SI, V4QI, V4QI)) DEF_MIPS_FTYPE (2, (SI, V4QI, V4QI))
DEF_MIPS_FTYPE (2, (SI, V4SI, UQI))
DEF_MIPS_FTYPE (2, (SI, V8HI, UQI))
DEF_MIPS_FTYPE (1, (SI, VOID)) DEF_MIPS_FTYPE (1, (SI, VOID))
DEF_MIPS_FTYPE (2, (UDI, UDI, UDI)) DEF_MIPS_FTYPE (2, (UDI, UDI, UDI))
DEF_MIPS_FTYPE (2, (UDI, UV2SI, UV2SI)) DEF_MIPS_FTYPE (2, (UDI, UV2SI, UV2SI))
DEF_MIPS_FTYPE (2, (UDI, V2DI, UQI))
DEF_MIPS_FTYPE (2, (USI, V16QI, UQI))
DEF_MIPS_FTYPE (2, (USI, V4SI, UQI))
DEF_MIPS_FTYPE (2, (USI, V8HI, UQI))
DEF_MIPS_FTYPE (1, (USI, VOID)) DEF_MIPS_FTYPE (1, (USI, VOID))
DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, UQI))
DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (3, (UV16QI, UV16QI, UV16QI, UQI))
DEF_MIPS_FTYPE (3, (UV16QI, UV16QI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, V16QI))
DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, UQI))
DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, UV2DI))
DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV2DI, UQI))
DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV2DI, UV2DI))
DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, V2DI))
DEF_MIPS_FTYPE (2, (UV2DI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (1, (UV2DI, V2DF))
DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UQI)) DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UQI))
DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UV2SI)) DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UV2SI))
...@@ -82,10 +112,75 @@ DEF_MIPS_FTYPE (3, (UV4HI, UV4HI, UV4HI, USI)) ...@@ -82,10 +112,75 @@ DEF_MIPS_FTYPE (3, (UV4HI, UV4HI, UV4HI, USI))
DEF_MIPS_FTYPE (1, (UV4HI, UV8QI)) DEF_MIPS_FTYPE (1, (UV4HI, UV8QI))
DEF_MIPS_FTYPE (2, (UV4HI, UV8QI, UV8QI)) DEF_MIPS_FTYPE (2, (UV4HI, UV8QI, UV8QI))
DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, UQI))
DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV4SI, UQI))
DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, V4SI))
DEF_MIPS_FTYPE (2, (UV4SI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (1, (UV4SI, V4SF))
DEF_MIPS_FTYPE (2, (UV8HI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, UQI))
DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV8HI, UQI))
DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, V8HI))
DEF_MIPS_FTYPE (2, (UV8QI, UV4HI, UV4HI)) DEF_MIPS_FTYPE (2, (UV8QI, UV4HI, UV4HI))
DEF_MIPS_FTYPE (1, (UV8QI, UV8QI)) DEF_MIPS_FTYPE (1, (UV8QI, UV8QI))
DEF_MIPS_FTYPE (2, (UV8QI, UV8QI, UV8QI)) DEF_MIPS_FTYPE (2, (UV8QI, UV8QI, UV8QI))
DEF_MIPS_FTYPE (2, (V16QI, CVPOINTER, SI))
DEF_MIPS_FTYPE (1, (V16QI, HI))
DEF_MIPS_FTYPE (1, (V16QI, SI))
DEF_MIPS_FTYPE (2, (V16QI, UV16QI, UQI))
DEF_MIPS_FTYPE (2, (V16QI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (1, (V16QI, V16QI))
DEF_MIPS_FTYPE (2, (V16QI, V16QI, QI))
DEF_MIPS_FTYPE (2, (V16QI, V16QI, SI))
DEF_MIPS_FTYPE (2, (V16QI, V16QI, UQI))
DEF_MIPS_FTYPE (3, (V16QI, V16QI, UQI, SI))
DEF_MIPS_FTYPE (3, (V16QI, V16QI, UQI, V16QI))
DEF_MIPS_FTYPE (2, (V16QI, V16QI, V16QI))
DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, SI))
DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, UQI))
DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, V16QI))
DEF_MIPS_FTYPE (1, (V2DF, DF))
DEF_MIPS_FTYPE (1, (V2DF, UV2DI))
DEF_MIPS_FTYPE (1, (V2DF, V2DF))
DEF_MIPS_FTYPE (2, (V2DF, V2DF, V2DF))
DEF_MIPS_FTYPE (3, (V2DF, V2DF, V2DF, V2DF))
DEF_MIPS_FTYPE (2, (V2DF, V2DF, V2DI))
DEF_MIPS_FTYPE (1, (V2DF, V2DI))
DEF_MIPS_FTYPE (1, (V2DF, V4SF))
DEF_MIPS_FTYPE (1, (V2DF, V4SI))
DEF_MIPS_FTYPE (2, (V2DI, CVPOINTER, SI))
DEF_MIPS_FTYPE (1, (V2DI, DI))
DEF_MIPS_FTYPE (1, (V2DI, HI))
DEF_MIPS_FTYPE (2, (V2DI, UV2DI, UQI))
DEF_MIPS_FTYPE (2, (V2DI, UV2DI, UV2DI))
DEF_MIPS_FTYPE (2, (V2DI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (1, (V2DI, V2DF))
DEF_MIPS_FTYPE (2, (V2DI, V2DF, V2DF))
DEF_MIPS_FTYPE (1, (V2DI, V2DI))
DEF_MIPS_FTYPE (2, (V2DI, V2DI, QI))
DEF_MIPS_FTYPE (2, (V2DI, V2DI, SI))
DEF_MIPS_FTYPE (2, (V2DI, V2DI, UQI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, UQI, DI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, UQI, V2DI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (2, (V2DI, V2DI, V2DI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, SI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, UQI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, V2DI))
DEF_MIPS_FTYPE (3, (V2DI, V2DI, V4SI, V4SI))
DEF_MIPS_FTYPE (2, (V2DI, V4SI, V4SI))
DEF_MIPS_FTYPE (1, (V2HI, SI)) DEF_MIPS_FTYPE (1, (V2HI, SI))
DEF_MIPS_FTYPE (2, (V2HI, SI, SI)) DEF_MIPS_FTYPE (2, (V2HI, SI, SI))
DEF_MIPS_FTYPE (3, (V2HI, SI, SI, SI)) DEF_MIPS_FTYPE (3, (V2HI, SI, SI, SI))
...@@ -118,12 +213,74 @@ DEF_MIPS_FTYPE (1, (V4QI, V4QI)) ...@@ -118,12 +213,74 @@ DEF_MIPS_FTYPE (1, (V4QI, V4QI))
DEF_MIPS_FTYPE (2, (V4QI, V4QI, SI)) DEF_MIPS_FTYPE (2, (V4QI, V4QI, SI))
DEF_MIPS_FTYPE (2, (V4QI, V4QI, V4QI)) DEF_MIPS_FTYPE (2, (V4QI, V4QI, V4QI))
DEF_MIPS_FTYPE (1, (V4SF, SF))
DEF_MIPS_FTYPE (1, (V4SF, UV4SI))
DEF_MIPS_FTYPE (2, (V4SF, V2DF, V2DF))
DEF_MIPS_FTYPE (1, (V4SF, V4SF))
DEF_MIPS_FTYPE (2, (V4SF, V4SF, V4SF))
DEF_MIPS_FTYPE (3, (V4SF, V4SF, V4SF, V4SF))
DEF_MIPS_FTYPE (2, (V4SF, V4SF, V4SI))
DEF_MIPS_FTYPE (1, (V4SF, V4SI))
DEF_MIPS_FTYPE (1, (V4SF, V8HI))
DEF_MIPS_FTYPE (2, (V4SI, CVPOINTER, SI))
DEF_MIPS_FTYPE (1, (V4SI, HI))
DEF_MIPS_FTYPE (1, (V4SI, SI))
DEF_MIPS_FTYPE (2, (V4SI, UV4SI, UQI))
DEF_MIPS_FTYPE (2, (V4SI, UV4SI, UV4SI))
DEF_MIPS_FTYPE (2, (V4SI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (2, (V4SI, V2DF, V2DF))
DEF_MIPS_FTYPE (1, (V4SI, V4SF))
DEF_MIPS_FTYPE (2, (V4SI, V4SF, V4SF))
DEF_MIPS_FTYPE (1, (V4SI, V4SI))
DEF_MIPS_FTYPE (2, (V4SI, V4SI, QI))
DEF_MIPS_FTYPE (2, (V4SI, V4SI, SI))
DEF_MIPS_FTYPE (2, (V4SI, V4SI, UQI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, UQI, SI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, UQI, V4SI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (2, (V4SI, V4SI, V4SI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, SI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, UQI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, V4SI))
DEF_MIPS_FTYPE (3, (V4SI, V4SI, V8HI, V8HI))
DEF_MIPS_FTYPE (2, (V4SI, V8HI, V8HI))
DEF_MIPS_FTYPE (2, (V8HI, CVPOINTER, SI))
DEF_MIPS_FTYPE (1, (V8HI, HI))
DEF_MIPS_FTYPE (1, (V8HI, SI))
DEF_MIPS_FTYPE (2, (V8HI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (2, (V8HI, UV8HI, UQI))
DEF_MIPS_FTYPE (2, (V8HI, UV8HI, UV8HI))
DEF_MIPS_FTYPE (2, (V8HI, V16QI, V16QI))
DEF_MIPS_FTYPE (2, (V8HI, V4SF, V4SF))
DEF_MIPS_FTYPE (1, (V8HI, V8HI))
DEF_MIPS_FTYPE (2, (V8HI, V8HI, QI))
DEF_MIPS_FTYPE (2, (V8HI, V8HI, SI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, SI, UQI))
DEF_MIPS_FTYPE (2, (V8HI, V8HI, UQI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, UQI, SI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, UQI, V8HI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, UV16QI, UV16QI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, V16QI, V16QI))
DEF_MIPS_FTYPE (2, (V8HI, V8HI, V8HI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, SI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, UQI))
DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, V8HI))
DEF_MIPS_FTYPE (2, (V8QI, V4HI, V4HI)) DEF_MIPS_FTYPE (2, (V8QI, V4HI, V4HI))
DEF_MIPS_FTYPE (1, (V8QI, V8QI)) DEF_MIPS_FTYPE (1, (V8QI, V8QI))
DEF_MIPS_FTYPE (2, (V8QI, V8QI, V8QI)) DEF_MIPS_FTYPE (2, (V8QI, V8QI, V8QI))
DEF_MIPS_FTYPE (2, (VOID, SI, CVPOINTER)) DEF_MIPS_FTYPE (2, (VOID, SI, CVPOINTER))
DEF_MIPS_FTYPE (2, (VOID, SI, SI)) DEF_MIPS_FTYPE (2, (VOID, SI, SI))
DEF_MIPS_FTYPE (2, (VOID, UQI, SI))
DEF_MIPS_FTYPE (1, (VOID, USI)) DEF_MIPS_FTYPE (1, (VOID, USI))
DEF_MIPS_FTYPE (3, (VOID, V16QI, CVPOINTER, SI))
DEF_MIPS_FTYPE (3, (VOID, V2DF, POINTER, SI))
DEF_MIPS_FTYPE (3, (VOID, V2DI, CVPOINTER, SI))
DEF_MIPS_FTYPE (2, (VOID, V2HI, V2HI)) DEF_MIPS_FTYPE (2, (VOID, V2HI, V2HI))
DEF_MIPS_FTYPE (2, (VOID, V4QI, V4QI)) DEF_MIPS_FTYPE (2, (VOID, V4QI, V4QI))
DEF_MIPS_FTYPE (3, (VOID, V4SF, POINTER, SI))
DEF_MIPS_FTYPE (3, (VOID, V4SI, CVPOINTER, SI))
DEF_MIPS_FTYPE (3, (VOID, V8HI, CVPOINTER, SI))
...@@ -24,11 +24,17 @@ VECTOR_MODES (INT, 4); /* V4QI V2HI */ ...@@ -24,11 +24,17 @@ VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
/* For MIPS MSA 128 bits. */
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
VECTOR_MODES (FLOAT, 16); /* V4SF V2DF */
/* Double-sized vector modes for vec_concat. */ /* Double-sized vector modes for vec_concat. */
VECTOR_MODE (INT, QI, 16); /* V16QI */ VECTOR_MODE (INT, QI, 32); /* V32QI */
VECTOR_MODE (INT, HI, 8); /* V8HI */ VECTOR_MODE (INT, HI, 16); /* V16HI */
VECTOR_MODE (INT, SI, 4); /* V4SI */ VECTOR_MODE (INT, SI, 8); /* V8SI */
VECTOR_MODE (FLOAT, SF, 4); /* V4SF */ VECTOR_MODE (INT, DI, 4); /* V4DI */
VECTOR_MODE (FLOAT, SF, 8); /* V8SF */
VECTOR_MODE (FLOAT, DF, 4); /* V4DF */
VECTOR_MODES (FRACT, 4); /* V4QQ V2HQ */ VECTOR_MODES (FRACT, 4); /* V4QQ V2HQ */
VECTOR_MODES (UFRACT, 4); /* V4UQQ V2UHQ */ VECTOR_MODES (UFRACT, 4); /* V4UQQ V2UHQ */
......
...@@ -197,8 +197,9 @@ extern bool mips_stack_address_p (rtx, machine_mode); ...@@ -197,8 +197,9 @@ extern bool mips_stack_address_p (rtx, machine_mode);
extern int mips_address_insns (rtx, machine_mode, bool); extern int mips_address_insns (rtx, machine_mode, bool);
extern int mips_const_insns (rtx); extern int mips_const_insns (rtx);
extern int mips_split_const_insns (rtx); extern int mips_split_const_insns (rtx);
extern int mips_split_128bit_const_insns (rtx);
extern int mips_load_store_insns (rtx, rtx_insn *); extern int mips_load_store_insns (rtx, rtx_insn *);
extern int mips_idiv_insns (void); extern int mips_idiv_insns (machine_mode);
extern rtx_insn *mips_emit_move (rtx, rtx); extern rtx_insn *mips_emit_move (rtx, rtx);
#ifdef RTX_CODE #ifdef RTX_CODE
extern void mips_emit_binary (enum rtx_code, rtx, rtx, rtx); extern void mips_emit_binary (enum rtx_code, rtx, rtx, rtx);
...@@ -216,6 +217,11 @@ extern bool mips_split_move_p (rtx, rtx, enum mips_split_type); ...@@ -216,6 +217,11 @@ extern bool mips_split_move_p (rtx, rtx, enum mips_split_type);
extern void mips_split_move (rtx, rtx, enum mips_split_type); extern void mips_split_move (rtx, rtx, enum mips_split_type);
extern bool mips_split_move_insn_p (rtx, rtx, rtx); extern bool mips_split_move_insn_p (rtx, rtx, rtx);
extern void mips_split_move_insn (rtx, rtx, rtx); extern void mips_split_move_insn (rtx, rtx, rtx);
extern void mips_split_128bit_move (rtx, rtx);
extern bool mips_split_128bit_move_p (rtx, rtx);
extern void mips_split_msa_copy_d (rtx, rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_split_msa_insert_d (rtx, rtx, rtx, rtx);
extern void mips_split_msa_fill_d (rtx, rtx);
extern const char *mips_output_move (rtx, rtx); extern const char *mips_output_move (rtx, rtx);
extern bool mips_cfun_has_cprestore_slot_p (void); extern bool mips_cfun_has_cprestore_slot_p (void);
extern bool mips_cprestore_address_p (rtx, bool); extern bool mips_cprestore_address_p (rtx, bool);
...@@ -278,6 +284,15 @@ extern void mips_expand_before_return (void); ...@@ -278,6 +284,15 @@ extern void mips_expand_before_return (void);
extern void mips_expand_epilogue (bool); extern void mips_expand_epilogue (bool);
extern bool mips_can_use_return_insn (void); extern bool mips_can_use_return_insn (void);
extern bool mips_const_vector_same_val_p (rtx, machine_mode);
extern bool mips_const_vector_same_bytes_p (rtx, machine_mode);
extern bool mips_const_vector_same_int_p (rtx, machine_mode, HOST_WIDE_INT,
HOST_WIDE_INT);
extern bool mips_const_vector_shuffle_set_p (rtx, machine_mode);
extern bool mips_const_vector_bitimm_set_p (rtx, machine_mode);
extern bool mips_const_vector_bitimm_clr_p (rtx, machine_mode);
extern rtx mips_msa_vec_parallel_const_half (machine_mode, bool);
extern rtx mips_gen_const_int_vector (machine_mode, int);
extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class, extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class,
machine_mode); machine_mode);
extern bool mips_cannot_change_mode_class (machine_mode, extern bool mips_cannot_change_mode_class (machine_mode,
...@@ -305,6 +320,7 @@ extern const char *mips_output_sync (void); ...@@ -305,6 +320,7 @@ extern const char *mips_output_sync (void);
extern const char *mips_output_sync_loop (rtx_insn *, rtx *); extern const char *mips_output_sync_loop (rtx_insn *, rtx *);
extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *); extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *);
extern const char *mips_output_division (const char *, rtx *); extern const char *mips_output_division (const char *, rtx *);
extern const char *mips_msa_output_division (const char *, rtx *);
extern const char *mips_output_probe_stack_range (rtx, rtx); extern const char *mips_output_probe_stack_range (rtx, rtx);
extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int); extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int);
extern unsigned int mips_hard_regno_nregs (int, machine_mode); extern unsigned int mips_hard_regno_nregs (int, machine_mode);
...@@ -343,6 +359,7 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx)); ...@@ -343,6 +359,7 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_expand_vec_minmax (rtx, rtx, rtx, extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool); rtx (*) (rtx, rtx, rtx), bool);
extern int mips_ldst_scaled_shift (machine_mode);
extern bool mips_signed_immediate_p (unsigned HOST_WIDE_INT, int, int); extern bool mips_signed_immediate_p (unsigned HOST_WIDE_INT, int, int);
extern bool mips_unsigned_immediate_p (unsigned HOST_WIDE_INT, int, int); extern bool mips_unsigned_immediate_p (unsigned HOST_WIDE_INT, int, int);
extern const char *umips_output_save_restore (bool, rtx); extern const char *umips_output_save_restore (bool, rtx);
...@@ -372,5 +389,6 @@ extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code); ...@@ -372,5 +389,6 @@ extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code);
#endif #endif
extern void mips_register_frame_header_opt (void); extern void mips_register_frame_header_opt (void);
extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
#endif /* ! GCC_MIPS_PROTOS_H */ #endif /* ! GCC_MIPS_PROTOS_H */
...@@ -472,6 +472,12 @@ struct mips_cpu_info { ...@@ -472,6 +472,12 @@ struct mips_cpu_info {
builtin_define ("__mips_dsp_rev=1"); \ builtin_define ("__mips_dsp_rev=1"); \
} \ } \
\ \
if (ISA_HAS_MSA) \
{ \
builtin_define ("__mips_msa"); \
builtin_define ("__mips_msa_width=128"); \
} \
\
MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \ MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \
MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \ MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \
\ \
...@@ -824,7 +830,8 @@ struct mips_cpu_info { ...@@ -824,7 +830,8 @@ struct mips_cpu_info {
--with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are --with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are
specified. specified.
--with-nan is ignored if -mnan is specified. --with-nan is ignored if -mnan is specified.
--with-fp-32 is ignored if -msoft-float, -msingle-float or -mfp are specified. --with-fp-32 is ignored if -msoft-float, -msingle-float, -mmsa or -mfp are
specified.
--with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg --with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg
or -mno-odd-spreg are specified. or -mno-odd-spreg are specified.
--with-divide is ignored if -mdivide-traps or -mdivide-breaks are --with-divide is ignored if -mdivide-traps or -mdivide-breaks are
...@@ -841,7 +848,7 @@ struct mips_cpu_info { ...@@ -841,7 +848,7 @@ struct mips_cpu_info {
{"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \ {"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \
{"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \ {"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
{"fp_32", "%{" OPT_ARCH32 \ {"fp_32", "%{" OPT_ARCH32 \
":%{!msoft-float:%{!msingle-float:%{!mfp*:-mfp%(VALUE)}}}}" }, \ ":%{!msoft-float:%{!msingle-float:%{!mfp*:%{!mmsa:-mfp%(VALUE)}}}}}" }, \
{"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \ {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \
"%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \ "%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \
{"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \ {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
...@@ -1175,6 +1182,9 @@ struct mips_cpu_info { ...@@ -1175,6 +1182,9 @@ struct mips_cpu_info {
/* Revision 2 of the DSP ASE is available. */ /* Revision 2 of the DSP ASE is available. */
#define ISA_HAS_DSPR2 (TARGET_DSPR2 && !TARGET_MIPS16) #define ISA_HAS_DSPR2 (TARGET_DSPR2 && !TARGET_MIPS16)
/* The MSA ASE is available. */
#define ISA_HAS_MSA (TARGET_MSA && !TARGET_MIPS16)
/* True if the result of a load is not available to the next instruction. /* True if the result of a load is not available to the next instruction.
A nop will then be needed between instructions like "lw $4,..." A nop will then be needed between instructions like "lw $4,..."
and "addiu $4,$4,1". */ and "addiu $4,$4,1". */
...@@ -1316,6 +1326,7 @@ struct mips_cpu_info { ...@@ -1316,6 +1326,7 @@ struct mips_cpu_info {
%{meva} %{mno-eva} \ %{meva} %{mno-eva} \
%{mvirt} %{mno-virt} \ %{mvirt} %{mno-virt} \
%{mxpa} %{mno-xpa} \ %{mxpa} %{mno-xpa} \
%{mmsa} %{mno-msa} \
%{msmartmips} %{mno-smartmips} \ %{msmartmips} %{mno-smartmips} \
%{mmt} %{mno-mt} \ %{mmt} %{mno-mt} \
%{mfix-rm7000} %{mno-fix-rm7000} \ %{mfix-rm7000} %{mno-fix-rm7000} \
...@@ -1487,6 +1498,11 @@ FP_ASM_SPEC "\ ...@@ -1487,6 +1498,11 @@ FP_ASM_SPEC "\
#define MIN_UNITS_PER_WORD 4 #define MIN_UNITS_PER_WORD 4
#endif #endif
/* Width of a MSA vector register in bytes. */
#define UNITS_PER_MSA_REG 16
/* Width of a MSA vector register in bits. */
#define BITS_PER_MSA_REG (UNITS_PER_MSA_REG * BITS_PER_UNIT)
/* For MIPS, width of a floating point register. */ /* For MIPS, width of a floating point register. */
#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4) #define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
...@@ -1559,8 +1575,11 @@ FP_ASM_SPEC "\ ...@@ -1559,8 +1575,11 @@ FP_ASM_SPEC "\
/* 8 is observed right on a DECstation and on riscos 4.02. */ /* 8 is observed right on a DECstation and on riscos 4.02. */
#define STRUCTURE_SIZE_BOUNDARY 8 #define STRUCTURE_SIZE_BOUNDARY 8
/* There is no point aligning anything to a rounder boundary than this. */ /* There is no point aligning anything to a rounder boundary than
#define BIGGEST_ALIGNMENT LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE, unless under MSA the bigggest alignment is
BITS_PER_MSA_REG. */
#define BIGGEST_ALIGNMENT \
(ISA_HAS_MSA ? BITS_PER_MSA_REG : LONG_DOUBLE_TYPE_SIZE)
/* All accesses must be aligned. */ /* All accesses must be aligned. */
#define STRICT_ALIGNMENT 1 #define STRICT_ALIGNMENT 1
...@@ -1667,7 +1686,7 @@ FP_ASM_SPEC "\ ...@@ -1667,7 +1686,7 @@ FP_ASM_SPEC "\
/* The [d]clz instructions have the natural values at 0. */ /* The [d]clz instructions have the natural values at 0. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
((VALUE) = GET_MODE_BITSIZE (MODE), 2) ((VALUE) = GET_MODE_UNIT_BITSIZE (MODE), 2)
/* Standard register usage. */ /* Standard register usage. */
...@@ -1798,6 +1817,10 @@ FP_ASM_SPEC "\ ...@@ -1798,6 +1817,10 @@ FP_ASM_SPEC "\
#define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1) #define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
#define MD_DBX_FIRST (FP_DBX_FIRST + FP_REG_NUM) #define MD_DBX_FIRST (FP_DBX_FIRST + FP_REG_NUM)
#define MSA_REG_FIRST FP_REG_FIRST
#define MSA_REG_LAST FP_REG_LAST
#define MSA_REG_NUM FP_REG_NUM
/* The DWARF 2 CFA column which tracks the return address from a /* The DWARF 2 CFA column which tracks the return address from a
signal handler context. This means that to maintain backwards signal handler context. This means that to maintain backwards
compatibility, no hard register can be assigned this column if it compatibility, no hard register can be assigned this column if it
...@@ -1886,8 +1909,11 @@ FP_ASM_SPEC "\ ...@@ -1886,8 +1909,11 @@ FP_ASM_SPEC "\
/* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */ /* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */
#define ACC_REG_P(REGNO) \ #define ACC_REG_P(REGNO) \
(MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO)) (MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO))
#define MSA_REG_P(REGNO) \
((unsigned int) ((int) (REGNO) - MSA_REG_FIRST) < MSA_REG_NUM)
#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X))) #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
#define MSA_REG_RTX_P(X) (REG_P (X) && MSA_REG_P (REGNO (X)))
/* True if X is (const (unspec [(const_int 0)] UNSPEC_GP)). This is used /* True if X is (const (unspec [(const_int 0)] UNSPEC_GP)). This is used
to initialize the mips16 gp pseudo register. */ to initialize the mips16 gp pseudo register. */
...@@ -1916,10 +1942,12 @@ FP_ASM_SPEC "\ ...@@ -1916,10 +1942,12 @@ FP_ASM_SPEC "\
mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE) mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE)
/* Odd-numbered single-precision registers are not considered callee-saved /* Odd-numbered single-precision registers are not considered callee-saved
for o32 FPXX as they will be clobbered when run on an FR=1 FPU. */ for o32 FPXX as they will be clobbered when run on an FR=1 FPU.
MSA vector registers with MODE > 64 bits are part clobbered too. */
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
(TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \ ((TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \
&& FP_REG_P (REGNO) && ((REGNO) & 1)) && FP_REG_P (REGNO) && ((REGNO) & 1)) \
|| (ISA_HAS_MSA && FP_REG_P (REGNO) && GET_MODE_SIZE (MODE) > 8))
#define MODES_TIEABLE_P mips_modes_tieable_p #define MODES_TIEABLE_P mips_modes_tieable_p
...@@ -2381,6 +2409,13 @@ enum reg_class ...@@ -2381,6 +2409,13 @@ enum reg_class
#define FP_ARG_FIRST (FP_REG_FIRST + 12) #define FP_ARG_FIRST (FP_REG_FIRST + 12)
#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) #define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
/* True if MODE is vector and supported in a MSA vector register. */
#define MSA_SUPPORTED_MODE_P(MODE) \
(ISA_HAS_MSA \
&& GET_MODE_SIZE (MODE) == UNITS_PER_MSA_REG \
&& (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT))
/* Temporary register that is used when restoring $gp after a call. $4 and $5 /* Temporary register that is used when restoring $gp after a call. $4 and $5
are used for returning complex double values in soft-float code, so $6 is the are used for returning complex double values in soft-float code, so $6 is the
first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use
...@@ -2606,6 +2641,7 @@ typedef struct mips_args { ...@@ -2606,6 +2641,7 @@ typedef struct mips_args {
we generally don't want to use them for copying arbitrary data. we generally don't want to use them for copying arbitrary data.
A single N-word move is usually the same cost as N single-word moves. */ A single N-word move is usually the same cost as N single-word moves. */
#define MOVE_MAX UNITS_PER_WORD #define MOVE_MAX UNITS_PER_WORD
/* We don't modify it for MSA as it is only used by the classic reload. */
#define MAX_MOVE_MAX 8 #define MAX_MOVE_MAX 8
/* Define this macro as a C expression which is nonzero if /* Define this macro as a C expression which is nonzero if
...@@ -2767,7 +2803,39 @@ typedef struct mips_args { ...@@ -2767,7 +2803,39 @@ typedef struct mips_args {
{ "gp", 28 + GP_REG_FIRST }, \ { "gp", 28 + GP_REG_FIRST }, \
{ "sp", 29 + GP_REG_FIRST }, \ { "sp", 29 + GP_REG_FIRST }, \
{ "fp", 30 + GP_REG_FIRST }, \ { "fp", 30 + GP_REG_FIRST }, \
{ "ra", 31 + GP_REG_FIRST } \ { "ra", 31 + GP_REG_FIRST }, \
{ "$w0", 0 + FP_REG_FIRST }, \
{ "$w1", 1 + FP_REG_FIRST }, \
{ "$w2", 2 + FP_REG_FIRST }, \
{ "$w3", 3 + FP_REG_FIRST }, \
{ "$w4", 4 + FP_REG_FIRST }, \
{ "$w5", 5 + FP_REG_FIRST }, \
{ "$w6", 6 + FP_REG_FIRST }, \
{ "$w7", 7 + FP_REG_FIRST }, \
{ "$w8", 8 + FP_REG_FIRST }, \
{ "$w9", 9 + FP_REG_FIRST }, \
{ "$w10", 10 + FP_REG_FIRST }, \
{ "$w11", 11 + FP_REG_FIRST }, \
{ "$w12", 12 + FP_REG_FIRST }, \
{ "$w13", 13 + FP_REG_FIRST }, \
{ "$w14", 14 + FP_REG_FIRST }, \
{ "$w15", 15 + FP_REG_FIRST }, \
{ "$w16", 16 + FP_REG_FIRST }, \
{ "$w17", 17 + FP_REG_FIRST }, \
{ "$w18", 18 + FP_REG_FIRST }, \
{ "$w19", 19 + FP_REG_FIRST }, \
{ "$w20", 20 + FP_REG_FIRST }, \
{ "$w21", 21 + FP_REG_FIRST }, \
{ "$w22", 22 + FP_REG_FIRST }, \
{ "$w23", 23 + FP_REG_FIRST }, \
{ "$w24", 24 + FP_REG_FIRST }, \
{ "$w25", 25 + FP_REG_FIRST }, \
{ "$w26", 26 + FP_REG_FIRST }, \
{ "$w27", 27 + FP_REG_FIRST }, \
{ "$w28", 28 + FP_REG_FIRST }, \
{ "$w29", 29 + FP_REG_FIRST }, \
{ "$w30", 30 + FP_REG_FIRST }, \
{ "$w31", 31 + FP_REG_FIRST } \
} }
#define DBR_OUTPUT_SEQEND(STREAM) \ #define DBR_OUTPUT_SEQEND(STREAM) \
......
...@@ -225,11 +225,12 @@ ...@@ -225,11 +225,12 @@
shift_shift" shift_shift"
(const_string "unknown")) (const_string "unknown"))
(define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor" (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor,simd_add"
(const_string "unknown")) (const_string "unknown"))
;; Main data type used by the insn ;; Main data type used by the insn
(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW" (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW,
V2DI,V4SI,V8HI,V16QI,V2DF,V4SF"
(const_string "unknown")) (const_string "unknown"))
;; True if the main data type is twice the size of a word. ;; True if the main data type is twice the size of a word.
...@@ -243,6 +244,13 @@ ...@@ -243,6 +244,13 @@
(const_string "yes")] (const_string "yes")]
(const_string "no"))) (const_string "no")))
;; True if the main data type is four times of the size of a word.
(define_attr "qword_mode" "no,yes"
(cond [(and (eq_attr "mode" "TI,TF")
(not (match_test "TARGET_64BIT")))
(const_string "yes")]
(const_string "no")))
;; Attributes describing a sync loop. These loops have the form: ;; Attributes describing a sync loop. These loops have the form:
;; ;;
;; if (RELEASE_BARRIER == YES) sync ;; if (RELEASE_BARRIER == YES) sync
...@@ -365,7 +373,12 @@ ...@@ -365,7 +373,12 @@
shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move, shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt, fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat, frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
multi,atomic,syncloop,nop,ghost,multimem" multi,atomic,syncloop,nop,ghost,multimem,
simd_div,simd_fclass,simd_flog2,simd_fadd,simd_fcvt,simd_fmul,simd_fmadd,
simd_fdiv,simd_bitins,simd_bitmov,simd_insert,simd_sld,simd_mul,simd_fcmp,
simd_fexp2,simd_int_arith,simd_bit,simd_shift,simd_splat,simd_fill,
simd_permute,simd_shf,simd_sat,simd_pcnt,simd_copy,simd_branch,simd_cmsa,
simd_fminmax,simd_logic,simd_move,simd_load,simd_store"
(cond [(eq_attr "jal" "!unset") (const_string "call") (cond [(eq_attr "jal" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load") (eq_attr "got" "load") (const_string "load")
...@@ -400,6 +413,11 @@ ...@@ -400,6 +413,11 @@
(eq_attr "move_type" "constN,shift_shift") (eq_attr "move_type" "constN,shift_shift")
(const_string "multi") (const_string "multi")
;; These types of move are split for quadword modes only.
(and (eq_attr "move_type" "move,const")
(eq_attr "qword_mode" "yes"))
(const_string "multi")
;; These types of move are split for doubleword modes only. ;; These types of move are split for doubleword modes only.
(and (eq_attr "move_type" "move,const") (and (eq_attr "move_type" "move,const")
(eq_attr "dword_mode" "yes")) (eq_attr "dword_mode" "yes"))
...@@ -486,6 +504,12 @@ ...@@ -486,6 +504,12 @@
(eq_attr "dword_mode" "yes")) (eq_attr "dword_mode" "yes"))
(const_int 2) (const_int 2)
;; Check for quadword moves that are decomposed into four
;; instructions.
(and (eq_attr "move_type" "mtc,mfc,move")
(eq_attr "qword_mode" "yes"))
(const_int 4)
;; Constants, loads and stores are handled by external routines. ;; Constants, loads and stores are handled by external routines.
(and (eq_attr "move_type" "const,constN") (and (eq_attr "move_type" "const,constN")
(eq_attr "dword_mode" "yes")) (eq_attr "dword_mode" "yes"))
...@@ -527,7 +551,7 @@ ...@@ -527,7 +551,7 @@
(const_int 2) (const_int 2)
(eq_attr "type" "idiv,idiv3") (eq_attr "type" "idiv,idiv3")
(symbol_ref "mips_idiv_insns ()") (symbol_ref "mips_idiv_insns (GET_MODE (PATTERN (insn)))")
(not (eq_attr "sync_mem" "none")) (not (eq_attr "sync_mem" "none"))
(symbol_ref "mips_sync_loop_insns (insn, operands)")] (symbol_ref "mips_sync_loop_insns (insn, operands)")]
...@@ -884,8 +908,10 @@ ...@@ -884,8 +908,10 @@
(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")]) (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
;; This attribute gives the upper-case mode name for one unit of a ;; This attribute gives the upper-case mode name for one unit of a
;; floating-point mode. ;; floating-point mode or vector mode.
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")]) (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF") (V4SF "SF")
(V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI")
(V2DF "DF")])
;; This attribute gives the integer mode that has the same size as a ;; This attribute gives the integer mode that has the same size as a
;; fixed-point mode. ;; fixed-point mode.
...@@ -941,6 +967,10 @@ ...@@ -941,6 +967,10 @@
;; from the same template. ;; from the same template.
(define_code_iterator any_mod [mod umod]) (define_code_iterator any_mod [mod umod])
;; This code iterator allows addition and subtraction to be generated
;; from the same template.
(define_code_iterator addsub [plus minus])
;; This code iterator allows all native floating-point comparisons to be ;; This code iterator allows all native floating-point comparisons to be
;; generated from the same template. ;; generated from the same template.
(define_code_iterator fcond [unordered uneq unlt unle eq lt le (define_code_iterator fcond [unordered uneq unlt unle eq lt le
...@@ -7634,6 +7664,9 @@ ...@@ -7634,6 +7664,9 @@
; ST-Microelectronics Loongson-2E/2F-specific patterns. ; ST-Microelectronics Loongson-2E/2F-specific patterns.
(include "loongson.md") (include "loongson.md")
; The MIPS MSA Instructions.
(include "mips-msa.md")
(define_c_enum "unspec" [ (define_c_enum "unspec" [
UNSPEC_ADDRESS_FIRST UNSPEC_ADDRESS_FIRST
]) ])
...@@ -299,6 +299,10 @@ mmicromips ...@@ -299,6 +299,10 @@ mmicromips
Target Report Mask(MICROMIPS) Target Report Mask(MICROMIPS)
Use microMIPS instructions. Use microMIPS instructions.
mmsa
Target Report Var(TARGET_MSA)
Use MIPS MSA Extension instructions.
mmt mmt
Target Report Var(TARGET_MT) Target Report Var(TARGET_MT)
Allow the use of MT instructions. Allow the use of MT instructions.
......
...@@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see
\ \
/* If no FP ABI option is specified, infer one from the \ /* If no FP ABI option is specified, infer one from the \
ABI/ISA level. */ \ ABI/ISA level. */ \
"%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \ "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \
MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \ MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \
\ \
/* Make sure that an endian option is always present. This makes \ /* Make sure that an endian option is always present. This makes \
things like LINK_SPEC easier to write. */ \ things like LINK_SPEC easier to write. */ \
......
...@@ -61,9 +61,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -61,9 +61,9 @@ along with GCC; see the file COPYING3. If not see
"%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \ "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \
\ \
/* If no FP ABI option is specified, infer one from the \ /* If no FP ABI option is specified, infer one from the \
ABI/ISA level. */ \ ABI/ISA level unless there is a conflicting option. */ \
"%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \ "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \
MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \ MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \
\ \
/* Base SPECs. */ \ /* Base SPECs. */ \
BASE_DRIVER_SELF_SPECS \ BASE_DRIVER_SELF_SPECS \
......
...@@ -35,12 +35,36 @@ ...@@ -35,12 +35,36 @@
(define_predicate "const_immlsa_operand" (define_predicate "const_immlsa_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 1, 4)"))) (match_test "IN_RANGE (INTVAL (op), 1, 4)")))
(define_predicate "const_msa_branch_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -1024, 1023)")))
(define_predicate "const_uimm3_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 7)")))
(define_predicate "const_uimm4_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 15)")))
(define_predicate "const_uimm5_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 31)")))
(define_predicate "const_uimm6_operand" (define_predicate "const_uimm6_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "UIMM6_OPERAND (INTVAL (op))"))) (match_test "UIMM6_OPERAND (INTVAL (op))")))
(define_predicate "const_uimm8_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 255)")))
(define_predicate "const_imm5_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -16, 15)")))
(define_predicate "const_imm10_operand" (define_predicate "const_imm10_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IMM10_OPERAND (INTVAL (op))"))) (match_test "IMM10_OPERAND (INTVAL (op))")))
...@@ -49,6 +73,22 @@ ...@@ -49,6 +73,22 @@
(ior (match_operand 0 "const_imm10_operand") (ior (match_operand 0 "const_imm10_operand")
(match_operand 0 "register_operand"))) (match_operand 0 "register_operand")))
(define_predicate "aq10b_operand"
(and (match_code "const_int")
(match_test "mips_signed_immediate_p (INTVAL (op), 10, 0)")))
(define_predicate "aq10h_operand"
(and (match_code "const_int")
(match_test "mips_signed_immediate_p (INTVAL (op), 10, 1)")))
(define_predicate "aq10w_operand"
(and (match_code "const_int")
(match_test "mips_signed_immediate_p (INTVAL (op), 10, 2)")))
(define_predicate "aq10d_operand"
(and (match_code "const_int")
(match_test "mips_signed_immediate_p (INTVAL (op), 10, 3)")))
(define_predicate "sle_operand" (define_predicate "sle_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
...@@ -61,6 +101,14 @@ ...@@ -61,6 +101,14 @@
(and (match_code "const_int,const_double,const_vector") (and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))"))) (match_test "op == CONST0_RTX (GET_MODE (op))")))
(define_predicate "const_m1_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
(define_predicate "reg_or_m1_operand"
(ior (match_operand 0 "const_m1_operand")
(match_operand 0 "register_operand")))
(define_predicate "reg_or_0_operand" (define_predicate "reg_or_0_operand"
(ior (and (match_operand 0 "const_0_operand") (ior (and (match_operand 0 "const_0_operand")
(not (match_test "TARGET_MIPS16"))) (not (match_test "TARGET_MIPS16")))
...@@ -74,6 +122,23 @@ ...@@ -74,6 +122,23 @@
(ior (match_operand 0 "const_1_operand") (ior (match_operand 0 "const_1_operand")
(match_operand 0 "register_operand"))) (match_operand 0 "register_operand")))
;; These are used in vec_merge, hence accept bitmask as const_int.
(define_predicate "const_exp_2_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 1)")))
(define_predicate "const_exp_4_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 3)")))
(define_predicate "const_exp_8_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 7)")))
(define_predicate "const_exp_16_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 15)")))
;; This is used for indexing into vectors, and hence only accepts const_int. ;; This is used for indexing into vectors, and hence only accepts const_int.
(define_predicate "const_0_or_1_operand" (define_predicate "const_0_or_1_operand"
(and (match_code "const_int") (and (match_code "const_int")
...@@ -507,3 +572,65 @@ ...@@ -507,3 +572,65 @@
(define_predicate "non_volatile_mem_operand" (define_predicate "non_volatile_mem_operand"
(and (match_operand 0 "memory_operand") (and (match_operand 0 "memory_operand")
(not (match_test "MEM_VOLATILE_P (op)")))) (not (match_test "MEM_VOLATILE_P (op)"))))
(define_predicate "const_vector_same_val_operand"
(match_code "const_vector")
{
return mips_const_vector_same_val_p (op, mode);
})
(define_predicate "const_vector_same_simm5_operand"
(match_code "const_vector")
{
return mips_const_vector_same_int_p (op, mode, -16, 15);
})
(define_predicate "const_vector_same_uimm5_operand"
(match_code "const_vector")
{
return mips_const_vector_same_int_p (op, mode, 0, 31);
})
(define_predicate "const_vector_same_ximm5_operand"
(match_code "const_vector")
{
return mips_const_vector_same_int_p (op, mode, -31, 31);
})
(define_predicate "const_vector_same_uimm6_operand"
(match_code "const_vector")
{
return mips_const_vector_same_int_p (op, mode, 0, 63);
})
(define_predicate "const_vector_same_uimm8_operand"
(match_code "const_vector")
{
return mips_const_vector_same_int_p (op, mode, 0, 255);
})
(define_predicate "par_const_vector_shf_set_operand"
(match_code "parallel")
{
return mips_const_vector_shuffle_set_p (op, mode);
})
(define_predicate "reg_or_vector_same_val_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_vector_same_val_operand")))
(define_predicate "reg_or_vector_same_simm5_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_vector_same_simm5_operand")))
(define_predicate "reg_or_vector_same_uimm5_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_vector_same_uimm5_operand")))
(define_predicate "reg_or_vector_same_ximm5_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_vector_same_ximm5_operand")))
(define_predicate "reg_or_vector_same_uimm6_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_vector_same_uimm6_operand")))
...@@ -849,6 +849,7 @@ Objective-C and Objective-C++ Dialects}. ...@@ -849,6 +849,7 @@ Objective-C and Objective-C++ Dialects}.
-mvirt -mno-virt @gol -mvirt -mno-virt @gol
-mxpa -mno-xpa @gol -mxpa -mno-xpa @gol
-mmicromips -mno-micromips @gol -mmicromips -mno-micromips @gol
-mmsa -mno-msa @gol
-mfpu=@var{fpu-type} @gol -mfpu=@var{fpu-type} @gol
-msmartmips -mno-smartmips @gol -msmartmips -mno-smartmips @gol
-mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol -mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol
......
...@@ -1641,6 +1641,9 @@ MIPS target can generate MIPS16 code. ...@@ -1641,6 +1641,9 @@ MIPS target can generate MIPS16 code.
MIPS target is a Loongson-2E or -2F target using an ABI that supports MIPS target is a Loongson-2E or -2F target using an ABI that supports
the Loongson vector modes. the Loongson vector modes.
@item mips_msa
MIPS target supports @code{-mmsa}, MIPS SIMD Architecture (MSA).
@item mips_newabi_large_long_double @item mips_newabi_large_long_double
MIPS target supports @code{long double} larger than @code{double} MIPS target supports @code{long double} larger than @code{double}
when using the new ABI. when using the new ABI.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment