in src/coreclr/jit/emitloongarch64.cpp [1456:1731]
void emitter::emitIns_R_R_R(
instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, insOpts opt) /* = INS_OPTS_NONE */
{
code_t code = emitInsCode(ins);
if (((INS_add_w <= ins) && (ins <= INS_crcc_w_d_w)) || ((INS_ldx_b <= ins) && (ins <= INS_ldle_d)) ||
((INS_stx_b <= ins) && (ins <= INS_stle_d)))
{
#ifdef DEBUG
switch (ins)
{
case INS_add_w:
case INS_add_d:
case INS_sub_w:
case INS_sub_d:
case INS_and:
case INS_or:
case INS_nor:
case INS_xor:
case INS_andn:
case INS_orn:
case INS_mul_w:
case INS_mul_d:
case INS_mulh_w:
case INS_mulh_wu:
case INS_mulh_d:
case INS_mulh_du:
case INS_mulw_d_w:
case INS_mulw_d_wu:
case INS_div_w:
case INS_div_wu:
case INS_div_d:
case INS_div_du:
case INS_mod_w:
case INS_mod_wu:
case INS_mod_d:
case INS_mod_du:
case INS_sll_w:
case INS_srl_w:
case INS_sra_w:
case INS_rotr_w:
case INS_sll_d:
case INS_srl_d:
case INS_sra_d:
case INS_rotr_d:
case INS_maskeqz:
case INS_masknez:
case INS_slt:
case INS_sltu:
case INS_ldx_b:
case INS_ldx_h:
case INS_ldx_w:
case INS_ldx_d:
case INS_ldx_bu:
case INS_ldx_hu:
case INS_ldx_wu:
case INS_stx_b:
case INS_stx_h:
case INS_stx_w:
case INS_stx_d:
case INS_ldgt_b:
case INS_ldgt_h:
case INS_ldgt_w:
case INS_ldgt_d:
case INS_ldle_b:
case INS_ldle_h:
case INS_ldle_w:
case INS_ldle_d:
case INS_stgt_b:
case INS_stgt_h:
case INS_stgt_w:
case INS_stgt_d:
case INS_stle_b:
case INS_stle_h:
case INS_stle_w:
case INS_stle_d:
case INS_crc_w_b_w:
case INS_crc_w_h_w:
case INS_crc_w_w_w:
case INS_crc_w_d_w:
case INS_crcc_w_b_w:
case INS_crcc_w_h_w:
case INS_crcc_w_w_w:
case INS_crcc_w_d_w:
break;
default:
NYI_LOONGARCH64("illegal ins within emitIns_R_R_R --1!");
}
#endif
assert(isGeneralRegister(reg1));
assert(isGeneralRegisterOrR0(reg2));
assert(isGeneralRegisterOrR0(reg3));
code |= (reg1 /*& 0x1f*/); // rd
code |= (reg2 /*& 0x1f*/) << 5; // rj
code |= (reg3 /*& 0x1f*/) << 10; // rk
}
else if ((INS_amswap_w <= ins) && (ins <= INS_ammin_db_du))
{
#ifdef DEBUG
switch (ins)
{
case INS_amswap_w:
case INS_amswap_d:
case INS_amswap_db_w:
case INS_amswap_db_d:
case INS_amadd_w:
case INS_amadd_d:
case INS_amadd_db_w:
case INS_amadd_db_d:
case INS_amand_w:
case INS_amand_d:
case INS_amand_db_w:
case INS_amand_db_d:
case INS_amor_w:
case INS_amor_d:
case INS_amor_db_w:
case INS_amor_db_d:
case INS_amxor_w:
case INS_amxor_d:
case INS_amxor_db_w:
case INS_amxor_db_d:
case INS_ammax_w:
case INS_ammax_d:
case INS_ammax_db_w:
case INS_ammax_db_d:
case INS_ammin_w:
case INS_ammin_d:
case INS_ammin_db_w:
case INS_ammin_db_d:
case INS_ammax_wu:
case INS_ammax_du:
case INS_ammax_db_wu:
case INS_ammax_db_du:
case INS_ammin_wu:
case INS_ammin_du:
case INS_ammin_db_wu:
case INS_ammin_db_du:
break;
default:
NYI_LOONGARCH64("illegal ins within emitIns_R_R_R --am!");
}
#endif
assert(isGeneralRegister(reg1));
assert(isGeneralRegisterOrR0(reg2));
assert(isGeneralRegisterOrR0(reg3));
code |= (reg1 /*& 0x1f*/); // rd
code |= (reg2 /*& 0x1f*/) << 10; // rk
code |= (reg3 /*& 0x1f*/) << 5; // rj
}
else if ((INS_fadd_s <= ins) && (ins <= INS_fcopysign_d))
{
#ifdef DEBUG
switch (ins)
{
case INS_fadd_s:
case INS_fadd_d:
case INS_fsub_s:
case INS_fsub_d:
case INS_fmul_s:
case INS_fmul_d:
case INS_fdiv_s:
case INS_fdiv_d:
case INS_fmax_s:
case INS_fmax_d:
case INS_fmin_s:
case INS_fmin_d:
case INS_fmaxa_s:
case INS_fmaxa_d:
case INS_fmina_s:
case INS_fmina_d:
case INS_fscaleb_s:
case INS_fscaleb_d:
case INS_fcopysign_s:
case INS_fcopysign_d:
break;
default:
NYI_LOONGARCH64("illegal ins within emitIns_R_R_R --2!");
}
#endif
assert(isFloatReg(reg1));
assert(isFloatReg(reg2));
assert(isFloatReg(reg3));
code |= (reg1 & 0x1f); // fd
code |= (reg2 & 0x1f) << 5; // fj
code |= (reg3 & 0x1f) << 10; // fk
}
else if ((INS_fldx_s <= ins) && (ins <= INS_fstle_d))
{
#ifdef DEBUG
switch (ins)
{
case INS_fldx_s:
case INS_fldx_d:
case INS_fstx_s:
case INS_fstx_d:
case INS_fldgt_s:
case INS_fldgt_d:
case INS_fldle_s:
case INS_fldle_d:
case INS_fstgt_s:
case INS_fstgt_d:
case INS_fstle_s:
case INS_fstle_d:
break;
default:
NYI_LOONGARCH64("illegal ins within emitIns_R_R_R --3!");
}
#endif
assert(isFloatReg(reg1));
assert(isGeneralRegisterOrR0(reg2));
assert(isGeneralRegisterOrR0(reg3));
code |= reg1 & 0x1f; // fd
code |= reg2 << 5; // rj
code |= reg3 << 10; // rk
}
#ifdef FEATURE_SIMD
else if ((INS_vldx == ins) || (INS_vstx == ins) || (INS_xvldx == ins) || (INS_xvstx == ins))
{
assert(isVectorRegister(reg1));
assert(isGeneralRegisterOrR0(reg2));
assert(isGeneralRegisterOrR0(reg3));
code |= reg1 & 0x1f; // vd(xd)
code |= reg2 << 5; // rj
code |= reg3 << 10; // rk
}
else if (((INS_vreplve_b <= ins) && (ins <= INS_vreplve_d)) || ((INS_xvreplve_b <= ins) && (ins <= INS_xvreplve_d)))
{
assert(isVectorRegister(reg1));
assert(isVectorRegister(reg2));
assert(isGeneralRegisterOrR0(reg3));
code |= (reg1 & 0x1f); // vd(xd)
code |= (reg2 & 0x1f) << 5; // vj(xj)
code |= reg3 << 10; // rk
}
else if (((INS_vfcmp_caf_s <= ins) && (ins <= INS_vshuf_d)) || ((INS_xvfcmp_caf_s <= ins) && (ins <= INS_xvperm_w)))
{
assert(isVectorRegister(reg1));
assert(isVectorRegister(reg2));
assert(isVectorRegister(reg3));
code |= (reg1 & 0x1f); // vd(xd)
code |= (reg2 & 0x1f) << 5; // vj(xj)
code |= (reg3 & 0x1f) << 10; // vk(xk)
}
#endif
else
{
NYI_LOONGARCH64("Unsupported instruction in emitIns_R_R_R");
}
instrDesc* id = emitNewInstr(attr);
id->idIns(ins);
id->idReg1(reg1);
id->idReg2(reg2);
id->idReg3(reg3);
id->idAddr()->iiaSetInstrEncode(code);
id->idCodeSize(4);
appendToCurIG(id);
}