emitAttr attr = emitActualTypeSize(targetType);
if (varTypeUsesFloatArgReg(treeNode))
{
- if (attr == EA_4BYTE)
- {
- GetEmitter()->emitIns_R_R(INS_fmov_s, attr, retReg, op1->GetRegNum());
- }
- else
- {
- GetEmitter()->emitIns_R_R(INS_fmov_d, attr, retReg, op1->GetRegNum());
- }
+ instruction ins = attr == EA_4BYTE ? INS_fmov_s : INS_fmov_d;
+ GetEmitter()->emitIns_R_R(ins, attr, retReg, op1->GetRegNum());
}
else
{
- if (attr == EA_4BYTE)
- {
- if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
- {
- GetEmitter()->emitIns_R_R_I_I(INS_bstrpick_d, EA_PTRSIZE, retReg, op1->GetRegNum(), 31, 0);
- }
- else
- {
- GetEmitter()->emitIns_R_R_I(INS_slli_w, attr, retReg, op1->GetRegNum(), 0);
- }
- }
- else
- GetEmitter()->emitIns_R_R_I(INS_ori, attr, retReg, op1->GetRegNum(), 0);
+ instruction ins = (attr == EA_4BYTE) ? INS_slli_w : INS_ori;
+ GetEmitter()->emitIns_R_R_I(ins, attr, retReg, op1->GetRegNum(), 0);
}
}
}
case GT_MUL:
if ((attr == EA_8BYTE) || (attr == EA_BYREF))
{
- op2 = treeNode->gtGetOp2();
- if (genActualTypeIsInt(op1) && genActualTypeIsInt(op2))
- ins = treeNode->IsUnsigned() ? INS_mulw_d_wu : INS_mulw_d_w;
- else
- ins = INS_mul_d;
+ ins = INS_mul_d;
}
else
{
- if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
- ins = INS_mulw_d_wu;
- else
- ins = INS_mul_w;
+ ins = INS_mul_w;
}
break;
switch (cmpSize)
{
case EA_4BYTE:
+ {
+ regNumber tmpRegOp1 = rsGetRsvdReg();
+ assert(regOp1 != tmpRegOp1);
if (cond.IsUnsigned())
{
imm = static_cast<uint32_t>(imm);
-
- regNumber tmpRegOp1 = rsGetRsvdReg();
- assert(regOp1 != tmpRegOp1);
emit->emitIns_R_R_I_I(INS_bstrpick_d, EA_8BYTE, tmpRegOp1, regOp1, 31, 0);
- regOp1 = tmpRegOp1;
}
else
{
imm = static_cast<int32_t>(imm);
+ emit->emitIns_R_R_I(INS_slli_w, EA_4BYTE, tmpRegOp1, regOp1, 0);
}
+ regOp1 = tmpRegOp1;
break;
+ }
case EA_8BYTE:
break;
case EA_1BYTE:
}
}
+#ifdef DEBUG
if (needCheckOv)
{
if (ins == INS_add_d)
}
else
{
-#ifdef DEBUG
printf("LOONGARCH64-Invalid ins for overflow check: %s\n", codeGen->genInsName(ins));
-#endif
assert(!"Invalid ins for overflow check");
}
}
+#endif
if (intConst != nullptr)
{
}
else if (dst->OperGet() == GT_MUL)
{
- if (!needCheckOv && !(dst->gtFlags & GTF_UNSIGNED))
+ if (!needCheckOv)
{
emitIns_R_R_R(ins, attr, dst->GetRegNum(), src1->GetRegNum(), src2->GetRegNum());
}
else
{
- if (needCheckOv)
- {
- assert(REG_R21 != dst->GetRegNum());
- assert(REG_R21 != src1->GetRegNum());
- assert(REG_R21 != src2->GetRegNum());
+ assert(REG_R21 != dst->GetRegNum());
+ assert(REG_R21 != src1->GetRegNum());
+ assert(REG_R21 != src2->GetRegNum());
+ assert(REG_RA != dst->GetRegNum());
+ assert(REG_RA != src1->GetRegNum());
+ assert(REG_RA != src2->GetRegNum());
- instruction ins2;
+ regNumber dstReg = dst->GetRegNum();
+ regNumber tmpReg1 = src1->GetRegNum();
+ regNumber tmpReg2 = src2->GetRegNum();
- if ((dst->gtFlags & GTF_UNSIGNED) != 0)
+ bool isUnsignd = (dst->gtFlags & GTF_UNSIGNED) != 0;
+ instruction ins2;
+ if (attr == EA_8BYTE)
+ {
+ if (isUnsignd)
{
- if (attr == EA_4BYTE)
- ins2 = INS_mulh_wu;
- else
- ins2 = INS_mulh_du;
+ ins2 = INS_mulh_du;
}
else
{
- if (attr == EA_8BYTE)
- ins2 = INS_mulh_d;
- else
- ins2 = INS_mulh_w;
+ ins2 = INS_mulh_d;
}
-
- emitIns_R_R_R(ins2, attr, REG_R21, src1->GetRegNum(), src2->GetRegNum());
- }
-
- // n * n bytes will store n bytes result
- emitIns_R_R_R(ins, attr, dst->GetRegNum(), src1->GetRegNum(), src2->GetRegNum());
-
- if ((dst->gtFlags & GTF_UNSIGNED) != 0)
- {
- if (attr == EA_4BYTE)
- emitIns_R_R_I_I(INS_bstrins_d, EA_8BYTE, dst->GetRegNum(), REG_R0, 63, 32);
}
-
- if (needCheckOv)
+ else
{
- assert(REG_R21 != dst->GetRegNum());
- assert(REG_R21 != src1->GetRegNum());
- assert(REG_R21 != src2->GetRegNum());
-
- if ((dst->gtFlags & GTF_UNSIGNED) != 0)
+ if (isUnsignd)
{
- codeGen->genJumpToThrowHlpBlk_la(SCK_OVERFLOW, INS_bne, REG_R21);
+ ins2 = INS_mulh_wu;
}
else
{
- assert(REG_RA != dst->GetRegNum());
- assert(REG_RA != src1->GetRegNum());
- assert(REG_RA != src2->GetRegNum());
- size_t imm = (EA_SIZE(attr) == EA_8BYTE) ? 63 : 31;
- emitIns_R_R_I(EA_SIZE(attr) == EA_8BYTE ? INS_srai_d : INS_srai_w, attr, REG_RA, dst->GetRegNum(),
- imm);
- codeGen->genJumpToThrowHlpBlk_la(SCK_OVERFLOW, INS_bne, REG_R21, nullptr, REG_RA);
+ ins2 = INS_mulh_w;
}
}
+ emitIns_R_R_R(ins2, EA_8BYTE, REG_R21, tmpReg1, tmpReg2);
+
+ // n * n bytes will store n bytes result
+ emitIns_R_R_R(ins, attr, dstReg, tmpReg1, tmpReg2);
+
+ if (isUnsignd)
+ {
+ tmpReg2 = REG_R0;
+ }
+ else
+ {
+ size_t imm = (EA_SIZE(attr) == EA_8BYTE) ? 63 : 31;
+ emitIns_R_R_I(EA_SIZE(attr) == EA_8BYTE ? INS_srai_d : INS_srai_w, attr, REG_RA, dstReg, imm);
+ tmpReg2 = REG_RA;
+ }
+
+ codeGen->genJumpToThrowHlpBlk_la(SCK_OVERFLOW, INS_bne, REG_R21, nullptr, tmpReg2);
}
}
else if (dst->OperIs(GT_AND, GT_AND_NOT, GT_OR, GT_XOR))
regNumber saveOperReg1 = REG_NA;
regNumber saveOperReg2 = REG_NA;
- if ((dst->gtFlags & GTF_UNSIGNED) && (attr == EA_8BYTE))
- {
- if (src1->gtType == TYP_INT)
- {
- assert(REG_R21 != regOp1);
- assert(REG_RA != regOp1);
- emitIns_R_R_I_I(INS_bstrpick_d, EA_8BYTE, REG_RA, regOp1, /*src1->GetRegNum(),*/ 31, 0);
- regOp1 = REG_RA; // dst->ExtractTempReg();
- }
- if (src2->gtType == TYP_INT)
- {
- assert(REG_R21 != regOp2);
- assert(REG_RA != regOp2);
- emitIns_R_R_I_I(INS_bstrpick_d, EA_8BYTE, REG_R21, regOp2, /*src2->GetRegNum(),*/ 31, 0);
- regOp2 = REG_R21; // dst->ExtractTempReg();
- }
- }
if (needCheckOv)
{
assert(!varTypeIsFloating(dst));