Chromium Code Reviews| Index: src/mips64/assembler-mips64.cc |
| diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc |
| index 99c3c9b01a1bf8c652430c68ffdaa31c301d9ffe..fef57f436b8a5c822ffadfc6a5aec8c93f921bb3 100644 |
| --- a/src/mips64/assembler-mips64.cc |
| +++ b/src/mips64/assembler-mips64.cc |
| @@ -79,6 +79,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
| // Probe for additional features at runtime. |
| base::CPU cpu; |
| if (cpu.has_fpu()) supported_ |= 1u << FPU; |
| + if (cpu.has_msa()) supported_ |= 1u << MIPS_SIMD; |
| #endif |
| } |
| @@ -1135,6 +1136,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((kArchVariant == kMips64r6) && IsEnabled(MIPS_SIMD)); |
|
ivica.bogosavljevic
2017/03/21 13:50:11
Is a prerequisite to have MSA to have MIPSR6 archi
dusan.simicic
2017/03/21 15:02:26
MSA instructions are available from MIPSr5 archite
|
| + 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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) { |
| @@ -3197,6 +3319,514 @@ 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((kArchVariant == kMips64r6) && 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) |
| +MSA_FILL(d) |
| +#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_s_d(Register rd, MSARegister ws, uint32_t n) { |
| + GenInstrMsaElm<Register, MSARegister>(COPY_S, ELM_DF_D, 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::insert_d(MSARegister wd, uint32_t n, Register rs) { |
| + GenInstrMsaElm<MSARegister, Register>(INSERT, ELM_DF_D, 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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((kArchVariant == kMips64r6) && 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) { |