noway_assert(tgtReg != REG_NA);
// We will use a temp register to load the lower bound and dimension size values.
- //
- // This should be simply:
- // regNumber tmpReg = arrIndex->GetSingleTempReg();
- //
- // However, since LSRA might give us an internal temp register that is the same as the dst
- // register, and the codegen here reuses the temp register after a definition of the target
- // register, we requested two internal registers. If one is the target register, we simply
- // use the other one. We can use ExtractTempReg() since it only asserts that there is at
- // least one available temporary register (not that there is exactly one, for instance).
- // Here, masking out tgtReg, there will be either 1 or 2.
-
- regNumber tmpReg = arrIndex->ExtractTempReg(~genRegMask(tgtReg));
+
+ regNumber tmpReg = arrIndex->GetSingleTempReg();
assert(tgtReg != tmpReg);
unsigned dim = arrIndex->gtCurrDim;
{
if (isMulOverflow)
{
- // This should be simply:
- // regNumber extraReg = dst->GetSingleTempReg();
- //
- // However, since LSRA might give us an internal temp register that is the same as the dst
- // register, and the codegen here reuses the temp register after a definition of the target
- // register, we requested two internal registers. If one is the target register, we simply
- // use the other one. We can use ExtractTempReg() since it only asserts that there is at
- // least one available temporary register (not that there is exactly one, for instance).
- // Here, masking out tgtReg, there will be either 1 or 2.
-
- regNumber extraReg = dst->ExtractTempReg(~genRegMask(dst->gtRegNum));
+ regNumber extraReg = dst->GetSingleTempReg();
assert(extraReg != dst->gtRegNum);
if ((dst->gtFlags & GTF_UNSIGNED) != 0)
if (tree->gtOverflow())
{
// Need a register different from target reg to check for overflow.
- info->internalIntCount = 1;
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
}
__fallthrough;
break;
case GT_ARR_INDEX:
- info->srcCount = 2;
- info->dstCount = 1;
-
- // We need one internal register when generating code for GT_ARR_INDEX, however the
- // register allocator always may just give us the same one as it gives us for the 'dst'
- // as a workaround we will just ask for two internal registers.
- //
- info->internalIntCount = 2;
+ info->srcCount = 2;
+ info->dstCount = 1;
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
// For GT_ARR_INDEX, the lifetime of the arrObj must be extended because it is actually used multiple
// times while the result is being computed.
case GT_MUL:
if (tree->gtOverflow())
{
- // Need a register different from target reg to check for overflow;
- // code generation requires the temp reg to live beyond the definition
- // of the target reg. Since we have no way to tell LSRA that, we request
- // two temp registers, and use one that is not the target reg.
- // TODO-ARM64-CQ: Figure out a way to only reserve one.
- info->internalIntCount = 2;
+ // Need a register different from target reg to check for overflow.
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
}
__fallthrough;
break;
case GT_ARR_INDEX:
- info->srcCount = 2;
- info->dstCount = 1;
-
- // We need one internal register when generating code for GT_ARR_INDEX. However, the
- // register allocator may give us the same one it gives us for 'dst'.
- // As a workaround we will just ask for two internal registers.
- // TODO-ARM64-CQ: Figure out a way to only reserve one.
- //
- info->internalIntCount = 2;
+ info->srcCount = 2;
+ info->dstCount = 1;
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
// For GT_ARR_INDEX, the lifetime of the arrObj must be extended because it is actually used multiple
// times while the result is being computed.