Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Unified Diff: src/mips/assembler-mips.cc

Issue 2740123004: MIPS[64]: Support for MSA instructions (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/mips/assembler-mips.cc
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 444d90f678095adff7898a6c48108fbc41d40409..557448fd6aa71edd1451dd0414cffccc69ebbec9 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -90,6 +90,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
if (cpu.is_fp64_mode()) supported_ |= 1u << FP64FPU;
#elif defined(FPU_MODE_FP64)
supported_ |= 1u << FP64FPU;
+ if (cpu.has_msa()) supported_ |= 1u << MIPS_SIMD;
#endif
#if defined(_MIPS_ARCH_MIPS32RX)
if (cpu.architecture() == 6) {
@@ -1167,6 +1168,127 @@ void Assembler::GenInstrJump(Opcode opcode,
BlockTrampolinePoolFor(1); // For associated delay slot.
}
+// MSA instructions
+void Assembler::GenInstrMsaI8(SecondaryField operation, uint32_t imm8,
+ MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid() && is_uint8(imm8));
+ Instr instr = MSA | operation | ((imm8 & kImm8Mask) << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaI5(SecondaryField operation, SecondaryField df,
+ int32_t imm5, MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid());
+ DCHECK((operation == MAXI_S) || (operation == MINI_S) ||
+ (operation == CEQI) || (operation == CLTI_S) ||
+ (operation == CLEI_S)
+ ? is_int5(imm5)
+ : is_uint5(imm5));
+ Instr instr = MSA | operation | df | ((imm5 & kImm5Mask) << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaBit(SecondaryField operation, SecondaryField df,
+ uint32_t m, MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid() && is_valid_msa_df_m(df, m));
+ Instr instr = MSA | operation | df | (m << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaI10(SecondaryField operation, SecondaryField df,
+ int32_t imm10, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(wd.is_valid() && is_int10(imm10));
+ Instr instr = MSA | operation | df | ((imm10 & kImm10Mask) << kWsShift) |
+ (wd.code() << kWdShift);
+ emit(instr);
+}
+
+template <typename RegType>
+void Assembler::GenInstrMsa3R(SecondaryField operation, SecondaryField df,
+ RegType t, MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(t.is_valid() && ws.is_valid() && wd.is_valid());
+ Instr instr = MSA | operation | df | (t.code() << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+template <typename DstType, typename SrcType>
+void Assembler::GenInstrMsaElm(SecondaryField operation, SecondaryField df,
+ uint32_t n, SrcType src, DstType dst) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(src.is_valid() && dst.is_valid() && is_valid_msa_df_n(df, n));
+ Instr instr = MSA | operation | df | (n << kWtShift) |
+ (src.code() << kWsShift) | (dst.code() << kWdShift) |
+ MSA_ELM_MINOR;
+ emit(instr);
+}
+
+void Assembler::GenInstrMsa3RF(SecondaryField operation, uint32_t df,
+ MSARegister wt, MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(wt.is_valid() && ws.is_valid() && wd.is_valid());
+ DCHECK(df < 2);
+ Instr instr = MSA | operation | (df << 21) | (wt.code() << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaVec(SecondaryField operation, MSARegister wt,
+ MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(wt.is_valid() && ws.is_valid() && wd.is_valid());
+ Instr instr = MSA | operation | (wt.code() << kWtShift) |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift) |
+ MSA_VEC_2R_2RF_MINOR;
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaMI10(SecondaryField operation, int32_t s10,
+ Register rs, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(rs.is_valid() && wd.is_valid() && is_int10(s10));
+ Instr instr = MSA | operation | ((s10 & kImm10Mask) << kWtShift) |
+ (rs.code() << kWsShift) | (wd.code() << kWdShift);
+ emit(instr);
+}
+
+void Assembler::GenInstrMsa2R(SecondaryField operation, SecondaryField df,
+ MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid());
+ Instr instr = MSA | MSA_2R_FORMAT | operation | df | (ws.code() << kWsShift) |
+ (wd.code() << kWdShift) | MSA_VEC_2R_2RF_MINOR;
+ emit(instr);
+}
+
+void Assembler::GenInstrMsa2RF(SecondaryField operation, SecondaryField df,
+ MSARegister ws, MSARegister wd) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid());
+ Instr instr = MSA | MSA_2RF_FORMAT | operation | df |
+ (ws.code() << kWsShift) | (wd.code() << kWdShift) |
+ MSA_VEC_2R_2RF_MINOR;
+ emit(instr);
+}
+
+void Assembler::GenInstrMsaBranch(SecondaryField operation, MSARegister wt,
+ int32_t offset16) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(wt.is_valid() && is_int16(offset16));
+ BlockTrampolinePoolScope block_trampoline_pool(this);
+ Instr instr =
+ COP1 | operation | (wt.code() << kWtShift) | (offset16 & kImm16Mask);
+ emit(instr);
+ BlockTrampolinePoolFor(1); // For associated delay slot.
+}
// Returns the next free trampoline entry.
int32_t Assembler::get_trampoline_entry(int32_t pos) {
@@ -2948,6 +3070,505 @@ void Assembler::bc1t(int16_t offset, uint16_t cc) {
emit(instr);
}
+// ---------- MSA instructions ------------
+#define MSA_BRANCH_LIST(V) \
+ V(bz_v, BZ_V) \
+ V(bz_b, BZ_B) \
+ V(bz_h, BZ_H) \
+ V(bz_w, BZ_W) \
+ V(bz_d, BZ_D) \
+ V(bnz_v, BNZ_V) \
+ V(bnz_b, BNZ_B) \
+ V(bnz_h, BNZ_H) \
+ V(bnz_w, BNZ_W) \
+ V(bnz_d, BNZ_D)
+
+#define MSA_BRANCH(name, opcode) \
+ void Assembler::name(MSARegister wt, int16_t offset) { \
+ GenInstrMsaBranch(opcode, wt, offset); \
+ }
+
+MSA_BRANCH_LIST(MSA_BRANCH)
+#undef MSA_BRANCH
+#undef MSA_BRANCH_LIST
+
+#define MSA_LD_ST_LIST(V) \
+ V(ld_b, LD_B) \
+ V(ld_h, LD_H) \
+ V(ld_w, LD_W) \
+ V(ld_d, LD_D) \
+ V(st_b, ST_B) \
+ V(st_h, ST_H) \
+ V(st_w, ST_W) \
+ V(st_d, ST_D)
+
+#define MSA_LD_ST(name, opcode) \
+ void Assembler::name(MSARegister wd, const MemOperand& rs) { \
+ if (is_int10(rs.offset())) { \
+ GenInstrMsaMI10(opcode, rs.offset(), rs.rm(), wd); \
+ } else { \
+ LoadRegPlusOffsetToAt(rs); \
+ GenInstrMsaMI10(opcode, 0, at, wd); \
+ } \
+ }
+
+MSA_LD_ST_LIST(MSA_LD_ST)
+#undef MSA_LD_ST
+#undef MSA_BRANCH_LIST
+
+#define MSA_I10_LIST(V) \
+ V(ldi_b, I5_DF_b) \
+ V(ldi_h, I5_DF_h) \
+ V(ldi_w, I5_DF_w) \
+ V(ldi_d, I5_DF_d)
+
+#define MSA_I10(name, format) \
+ void Assembler::name(MSARegister wd, int32_t imm10) { \
+ GenInstrMsaI10(LDI, format, imm10, wd); \
+ }
+MSA_I10_LIST(MSA_I10)
+#undef MSA_I10
+#undef MSA_I10_LIST
+
+#define MSA_I5_LIST(V) \
+ V(addvi, ADDVI) \
+ V(subvi, SUBVI) \
+ V(maxi_s, MAXI_S) \
+ V(maxi_u, MAXI_U) \
+ V(mini_s, MINI_S) \
+ V(mini_u, MINI_U) \
+ V(ceqi, CEQI) \
+ V(clti_s, CLTI_S) \
+ V(clti_u, CLTI_U) \
+ V(clei_s, CLEI_S) \
+ V(clei_u, CLEI_U)
+
+#define MSA_I5_FORMAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
+ uint32_t imm5) { \
+ GenInstrMsaI5(opcode, I5_DF_##format, imm5, ws, wd); \
+ }
+
+#define MSA_I5(name, opcode) \
+ MSA_I5_FORMAT(name, opcode, b) \
+ MSA_I5_FORMAT(name, opcode, h) \
+ MSA_I5_FORMAT(name, opcode, w) \
+ MSA_I5_FORMAT(name, opcode, d)
+
+MSA_I5_LIST(MSA_I5)
+#undef MSA_I5
+#undef MSA_I5_FORMAT
+#undef MSA_I5_LIST
+
+#define MSA_I8_LIST(V) \
+ V(andi_b, ANDI_B) \
+ V(ori_b, ORI_B) \
+ V(nori_b, NORI_B) \
+ V(xori_b, XORI_B) \
+ V(bmnzi_b, BMNZI_B) \
+ V(bmzi_b, BMZI_B) \
+ V(bseli_b, BSELI_B) \
+ V(shf_b, SHF_B) \
+ V(shf_h, SHF_H) \
+ V(shf_w, SHF_W)
+
+#define MSA_I8(name, opcode) \
+ void Assembler::name(MSARegister wd, MSARegister ws, uint32_t imm8) { \
+ GenInstrMsaI8(opcode, imm8, ws, wd); \
+ }
+
+MSA_I8_LIST(MSA_I8)
+#undef MSA_I8
+#undef MSA_I8_LIST
+
+#define MSA_VEC_LIST(V) \
+ V(and_v, AND_V) \
+ V(or_v, OR_V) \
+ V(nor_v, NOR_V) \
+ V(xor_v, XOR_V) \
+ V(bmnz_v, BMNZ_V) \
+ V(bmz_v, BMZ_V) \
+ V(bsel_v, BSEL_V)
+
+#define MSA_VEC(name, opcode) \
+ void Assembler::name(MSARegister wd, MSARegister ws, MSARegister wt) { \
+ GenInstrMsaVec(opcode, wt, ws, wd); \
+ }
+
+MSA_VEC_LIST(MSA_VEC)
+#undef MSA_VEC
+#undef MSA_VEC_LIST
+
+#define MSA_2R_LIST(V) \
+ V(pcnt, PCNT) \
+ V(nloc, NLOC) \
+ V(nlzc, NLZC)
+
+#define MSA_2R_FORMAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws) { \
+ GenInstrMsa2R(opcode, MSA_2R_DF_##format, ws, wd); \
+ }
+
+#define MSA_2R(name, opcode) \
+ MSA_2R_FORMAT(name, opcode, b) \
+ MSA_2R_FORMAT(name, opcode, h) \
+ MSA_2R_FORMAT(name, opcode, w) \
+ MSA_2R_FORMAT(name, opcode, d)
+
+MSA_2R_LIST(MSA_2R)
+#undef MSA_2R
+#undef MSA_2R_FORMAT
+#undef MSA_2R_LIST
+
+#define MSA_FILL(format) \
+ void Assembler::fill_##format(MSARegister wd, Register rs) { \
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD)); \
+ DCHECK(rs.is_valid() && wd.is_valid()); \
+ Instr instr = MSA | MSA_2R_FORMAT | FILL | MSA_2R_DF_##format | \
+ (rs.code() << kWsShift) | (wd.code() << kWdShift) | \
+ MSA_VEC_2R_2RF_MINOR; \
+ emit(instr); \
+ }
+
+MSA_FILL(b)
+MSA_FILL(h)
+MSA_FILL(w)
+#undef MSA_FILL
+
+#define MSA_2RF_LIST(V) \
+ V(fclass, FCLASS) \
+ V(ftrunc_s, FTRUNC_S) \
+ V(ftrunc_u, FTRUNC_U) \
+ V(fsqrt, FSQRT) \
+ V(frsqrt, FRSQRT) \
+ V(frcp, FRCP) \
+ V(frint, FRINT) \
+ V(flog2, FLOG2) \
+ V(fexupl, FEXUPL) \
+ V(fexupr, FEXUPR) \
+ V(ffql, FFQL) \
+ V(ffqr, FFQR) \
+ V(ftint_s, FTINT_S) \
+ V(ftint_u, FTINT_U) \
+ V(ffint_s, FFINT_S) \
+ V(ffint_u, FFINT_U)
+
+#define MSA_2RF_FORMAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws) { \
+ GenInstrMsa2RF(opcode, MSA_2RF_DF_##format, ws, wd); \
+ }
+
+#define MSA_2RF(name, opcode) \
+ MSA_2RF_FORMAT(name, opcode, w) \
+ MSA_2RF_FORMAT(name, opcode, d)
+
+MSA_2RF_LIST(MSA_2RF)
+#undef MSA_2RF
+#undef MSA_2RF_FORMAT
+#undef MSA_2RF_LIST
+
+#define MSA_3R_LIST(V) \
+ V(sll, SLL_MSA) \
+ V(sra, SRA_MSA) \
+ V(srl, SRL_MSA) \
+ V(bclr, BCLR) \
+ V(bset, BSET) \
+ V(bneg, BNEG) \
+ V(binsl, BINSL) \
+ V(binsr, BINSR) \
+ V(addv, ADDV) \
+ V(subv, SUBV) \
+ V(max_s, MAX_S) \
+ V(max_u, MAX_U) \
+ V(min_s, MIN_S) \
+ V(min_u, MIN_U) \
+ V(max_a, MAX_A) \
+ V(min_a, MIN_A) \
+ V(ceq, CEQ) \
+ V(clt_s, CLT_S) \
+ V(clt_u, CLT_U) \
+ V(cle_s, CLE_S) \
+ V(cle_u, CLE_U) \
+ V(add_a, ADD_A) \
+ V(adds_a, ADDS_A) \
+ V(adds_s, ADDS_S) \
+ V(adds_u, ADDS_U) \
+ V(ave_s, AVE_S) \
+ V(ave_u, AVE_U) \
+ V(aver_s, AVER_S) \
+ V(aver_u, AVER_U) \
+ V(subs_s, SUBS_S) \
+ V(subs_u, SUBS_U) \
+ V(subsus_u, SUBSUS_U) \
+ V(subsuu_s, SUBSUU_S) \
+ V(asub_s, ASUB_S) \
+ V(asub_u, ASUB_U) \
+ V(mulv, MULV) \
+ V(maddv, MADDV) \
+ V(msubv, MSUBV) \
+ V(div_s, DIV_S_MSA) \
+ V(div_u, DIV_U) \
+ V(mod_s, MOD_S) \
+ V(mod_u, MOD_U) \
+ V(dotp_s, DOTP_S) \
+ V(dotp_u, DOTP_U) \
+ V(dpadd_s, DPADD_S) \
+ V(dpadd_u, DPADD_U) \
+ V(dpsub_s, DPSUB_S) \
+ V(dpsub_u, DPSUB_U) \
+ V(pckev, PCKEV) \
+ V(pckod, PCKOD) \
+ V(ilvl, ILVL) \
+ V(ilvr, ILVR) \
+ V(ilvev, ILVEV) \
+ V(ilvod, ILVOD) \
+ V(vshf, VSHF) \
+ V(srar, SRAR) \
+ V(srlr, SRLR) \
+ V(hadd_s, HADD_S) \
+ V(hadd_u, HADD_U) \
+ V(hsub_s, HSUB_S) \
+ V(hsub_u, HSUB_U)
+
+#define MSA_3R_FORMAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
+ MSARegister wt) { \
+ GenInstrMsa3R<MSARegister>(opcode, MSA_3R_DF_##format, wt, ws, wd); \
+ }
+
+#define MSA_3R_FORMAT_SLD_SPLAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
+ Register rt) { \
+ GenInstrMsa3R<Register>(opcode, MSA_3R_DF_##format, rt, ws, wd); \
+ }
+
+#define MSA_3R(name, opcode) \
+ MSA_3R_FORMAT(name, opcode, b) \
+ MSA_3R_FORMAT(name, opcode, h) \
+ MSA_3R_FORMAT(name, opcode, w) \
+ MSA_3R_FORMAT(name, opcode, d)
+
+#define MSA_3R_SLD_SPLAT(name, opcode) \
+ MSA_3R_FORMAT_SLD_SPLAT(name, opcode, b) \
+ MSA_3R_FORMAT_SLD_SPLAT(name, opcode, h) \
+ MSA_3R_FORMAT_SLD_SPLAT(name, opcode, w) \
+ MSA_3R_FORMAT_SLD_SPLAT(name, opcode, d)
+
+MSA_3R_LIST(MSA_3R)
+MSA_3R_SLD_SPLAT(sld, SLD)
+MSA_3R_SLD_SPLAT(splat, SPLAT)
+
+#undef MSA_3R
+#undef MSA_3R_FORMAT
+#undef MSA_3R_FORMAT_SLD_SPLAT
+#undef MSA_3R_SLD_SPLAT
+#undef MSA_3R_LIST
+
+#define MSA_3RF_LIST1(V) \
+ V(fcaf, FCAF) \
+ V(fcun, FCUN) \
+ V(fceq, FCEQ) \
+ V(fcueq, FCUEQ) \
+ V(fclt, FCLT) \
+ V(fcult, FCULT) \
+ V(fcle, FCLE) \
+ V(fcule, FCULE) \
+ V(fsaf, FSAF) \
+ V(fsun, FSUN) \
+ V(fseq, FSEQ) \
+ V(fsueq, FSUEQ) \
+ V(fslt, FSLT) \
+ V(fsult, FSULT) \
+ V(fsle, FSLE) \
+ V(fsule, FSULE) \
+ V(fadd, FADD) \
+ V(fsub, FSUB) \
+ V(fmul, FMUL) \
+ V(fdiv, FDIV) \
+ V(fmadd, FMADD) \
+ V(fmsub, FMSUB) \
+ V(fexp2, FEXP2) \
+ V(fmin, FMIN) \
+ V(fmin_a, FMIN_A) \
+ V(fmax, FMAX) \
+ V(fmax_a, FMAX_A) \
+ V(fcor, FCOR) \
+ V(fcune, FCUNE) \
+ V(fcne, FCNE) \
+ V(fsor, FSOR) \
+ V(fsune, FSUNE) \
+ V(fsne, FSNE)
+
+#define MSA_3RF_LIST2(V) \
+ V(fexdo, FEXDO) \
+ V(ftq, FTQ) \
+ V(mul_q, MUL_Q) \
+ V(madd_q, MADD_Q) \
+ V(msub_q, MSUB_Q) \
+ V(mulr_q, MULR_Q) \
+ V(maddr_q, MADDR_Q) \
+ V(msubr_q, MSUBR_Q)
+
+#define MSA_3RF_FORMAT(name, opcode, df, df_c) \
+ void Assembler::name##_##df(MSARegister wd, MSARegister ws, \
+ MSARegister wt) { \
+ GenInstrMsa3RF(opcode, df_c, wt, ws, wd); \
+ }
+
+#define MSA_3RF_1(name, opcode) \
+ MSA_3RF_FORMAT(name, opcode, w, 0) \
+ MSA_3RF_FORMAT(name, opcode, d, 1)
+
+#define MSA_3RF_2(name, opcode) \
+ MSA_3RF_FORMAT(name, opcode, h, 0) \
+ MSA_3RF_FORMAT(name, opcode, w, 1)
+
+MSA_3RF_LIST1(MSA_3RF_1)
+MSA_3RF_LIST2(MSA_3RF_2)
+#undef MSA_3RF_1
+#undef MSA_3RF_2
+#undef MSA_3RF_FORMAT
+#undef MSA_3RF_LIST1
+#undef MSA_3RF_LIST2
+
+void Assembler::sldi_b(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_B, n, ws, wd);
+}
+
+void Assembler::sldi_h(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_H, n, ws, wd);
+}
+
+void Assembler::sldi_w(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_W, n, ws, wd);
+}
+
+void Assembler::sldi_d(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SLDI, ELM_DF_D, n, ws, wd);
+}
+
+void Assembler::splati_b(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_B, n, ws, wd);
+}
+
+void Assembler::splati_h(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_H, n, ws, wd);
+}
+
+void Assembler::splati_w(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_W, n, ws, wd);
+}
+
+void Assembler::splati_d(MSARegister wd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<MSARegister, MSARegister>(SPLATI, ELM_DF_D, n, ws, wd);
+}
+
+void Assembler::copy_s_b(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_B, n, ws, rd);
+}
+
+void Assembler::copy_s_h(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_H, n, ws, rd);
+}
+
+void Assembler::copy_s_w(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_W, n, ws, rd);
+}
+
+void Assembler::copy_u_b(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_B, n, ws, rd);
+}
+
+void Assembler::copy_u_h(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_H, n, ws, rd);
+}
+
+void Assembler::copy_u_w(Register rd, MSARegister ws, uint32_t n) {
+ GenInstrMsaElm<Register, MSARegister>(COPY_U, ELM_DF_W, n, ws, rd);
+}
+
+void Assembler::insert_b(MSARegister wd, uint32_t n, Register rs) {
+ GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_B, n, rs, wd);
+}
+
+void Assembler::insert_h(MSARegister wd, uint32_t n, Register rs) {
+ GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_H, n, rs, wd);
+}
+
+void Assembler::insert_w(MSARegister wd, uint32_t n, Register rs) {
+ GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_W, n, rs, wd);
+}
+
+void Assembler::insve_b(MSARegister wd, uint32_t n, MSARegister ws) {
+ GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_B, n, ws, wd);
+}
+
+void Assembler::insve_h(MSARegister wd, uint32_t n, MSARegister ws) {
+ GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_H, n, ws, wd);
+}
+
+void Assembler::insve_w(MSARegister wd, uint32_t n, MSARegister ws) {
+ GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_W, n, ws, wd);
+}
+
+void Assembler::insve_d(MSARegister wd, uint32_t n, MSARegister ws) {
+ GenInstrMsaElm<MSARegister, MSARegister>(INSVE, ELM_DF_D, n, ws, wd);
+}
+
+void Assembler::move_v(MSARegister wd, MSARegister ws) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(ws.is_valid() && wd.is_valid());
+ Instr instr = MSA | MOVE_V | (ws.code() << kWsShift) |
+ (wd.code() << kWdShift) | MSA_ELM_MINOR;
+ emit(instr);
+}
+
+void Assembler::ctcmsa(MSAControlRegister cd, Register rs) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(cd.is_valid() && rs.is_valid());
+ Instr instr = MSA | CTCMSA | (rs.code() << kWsShift) |
+ (cd.code() << kWdShift) | MSA_ELM_MINOR;
+ emit(instr);
+}
+
+void Assembler::cfcmsa(Register rd, MSAControlRegister cs) {
+ DCHECK(IsMipsArchVariant(kMips32r6) && IsEnabled(MIPS_SIMD));
+ DCHECK(rd.is_valid() && cs.is_valid());
+ Instr instr = MSA | CFCMSA | (cs.code() << kWsShift) |
+ (rd.code() << kWdShift) | MSA_ELM_MINOR;
+ emit(instr);
+}
+
+#define MSA_BIT_LIST(V) \
+ V(slli, SLLI) \
+ V(srai, SRAI) \
+ V(srli, SRLI) \
+ V(bclri, BCLRI) \
+ V(bseti, BSETI) \
+ V(bnegi, BNEGI) \
+ V(binsli, BINSLI) \
+ V(binsri, BINSRI) \
+ V(sat_s, SAT_S) \
+ V(sat_u, SAT_U) \
+ V(srari, SRARI) \
+ V(srlri, SRLRI)
+
+#define MSA_BIT_FORMAT(name, opcode, format) \
+ void Assembler::name##_##format(MSARegister wd, MSARegister ws, \
+ uint32_t m) { \
+ GenInstrMsaBit(opcode, BIT_DF_##format, m, ws, wd); \
+ }
+
+#define MSA_BIT(name, opcode) \
+ MSA_BIT_FORMAT(name, opcode, b) \
+ MSA_BIT_FORMAT(name, opcode, h) \
+ MSA_BIT_FORMAT(name, opcode, w) \
+ MSA_BIT_FORMAT(name, opcode, d)
+
+MSA_BIT_LIST(MSA_BIT)
+#undef MSA_BIT
+#undef MSA_BIT_FORMAT
+#undef MSA_BIT_LIST
int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
intptr_t pc_delta) {

Powered by Google App Engine
This is Rietveld 408576698